Objektorientierte Programmierung
             mit     extbase und fluid




            26.-27.01.2011
            Oliver Klee, typo3-coding@oliverklee.de
pibase und extbase
               sind   Frameworks
pibase und extbase
               sind   Frameworks

    pibase
pibase und extbase
               sind   Frameworks

    pibase       extbase
pibase und extbase
               sind   Frameworks
                           Backport
                             von

    pibase       extbase
pibase „unterstützt“
         hauptsächlich   prozeduralen Code
pibase „unterstützt“
         hauptsächlich   prozeduralen Code
tt_news-
                                  Hauptklasse




pibase „unterstützt“
         hauptsächlich   prozeduralen Code
tt_news-
                                  Hauptklasse




pibase „unterstützt“
         hauptsächlich   prozeduralen Code
tt_news-
                                  Hauptklasse




pibase „unterstützt“
         hauptsächlich   prozeduralen Code
tt_news-
                                  Hauptklasse


                                 > 400 0 Ze i le n …

pibase „unterstützt“
         hauptsächlich   prozeduralen Code
Monster-
    Klassen
extbase fördert
        lesbaren, gut wartbaren Code
news2-
                          Hauptklasse



extbase fördert
        lesbaren, gut wartbaren Code
news2-
                          Hauptklasse



extbase fördert
        lesbaren, gut wartbaren Code
news2-
                           Hauptklasse


                         c a . 26 0 Ze i le n …

extbase fördert
        lesbaren, gut wartbaren Code
extbase unterstützt
Domain-Driven Design (DDD)
extbase unterstützt
Domain-Driven Design (DDD)
class Book {
                        …
                      }




extbase unterstützt
Domain-Driven Design (DDD)
class Book {
                        …
                      }




extbase unterstützt
Domain-Driven Design (DDD)
fluid erlaubt
      mächtige HTML-Templates
fluid erlaubt
        mächtige HTML-Templates
<f:for each="{categories}" as="category">
    <table class="overview">
         <tr>
              <td>
                   <h1>{category.title}</h1>
              </td>
              <td>
                   <f:image src="{category.image}" width="42"/>
              </td>
         </tr>
    </table>
</f:for>
… und pibase eher nicht.
<!-- ###TEMPLATE_LATEST### begin
!    This is the template for the latest news, typically displayed on a frontpage
-->
<div class="news-latest-container">
!    <h2>###LATEST_HEADER###</h2>
!    <!-- ###CONTENT### begin
!    !      This is the part of the template substituted with the list of news:
!    -->
!    !    <!-- ###NEWS### begin
!    !    !    Template for a single item
!    !    -->
!    !    !      <div class="news-latest-item">
!    !    !    !    <span class="news-latest-date"><!--###LINK_ITEM###-->###NEWS_DATE### ###NEWS_TIME###<!--
###LINK_ITEM###--></span>
!    !    !    !    <h3><!--###LINK_ITEM###-->###NEWS_TITLE###<!--###LINK_ITEM###--></h3>
!    !    !    !    <!--###LINK_ITEM###-->###NEWS_IMAGE###<!--###LINK_ITEM###-->
!    !    !    !    ###NEWS_SUBHEADER###<hr class="clearer" />
!    !    !    !    ###CATWRAP_B### ###TEXT_CAT_LATEST### ###NEWS_CATEGORY### ###NEWS_CATEGORY_IMAGE###
###CATWRAP_E###
                 <div class="news-latest-morelink"><!--###LINK_ITEM###-->###MORE###<!--###LINK_ITEM###--></div>
!    !    !      </div>
!    !    <!-- ###NEWS### end-->!!
!    <!-- ###CONTENT### end -->
<div class="news-latest-gotoarchive"><!--###LINK_ARCHIVE###-->###GOTOARCHIVE###<!--###LINK_ARCHIVE###--></div>
</div>
<!-- ###TEMPLATE_LATEST### end -->
extbase macht vieles einfacher
extbase macht vieles einfacher
    die Entwicklung geht schneller
extbase macht vieles einfacher
    die Entwicklung geht schneller

    es ist weniger Code nötig
extbase macht vieles einfacher
    die Entwicklung geht schneller

    es ist weniger Code nötig

    Unit-Tests sind einfacher
extbase macht vieles einfacher
    die Entwicklung geht schneller

    es ist weniger Code nötig

    Unit-Tests sind einfacher

    HTML-Templates können mehr
extbase macht vieles einfacher
    die Entwicklung geht schneller

    es ist weniger Code nötig

    Unit-Tests sind einfacher

    HTML-Templates können mehr

    Einarbeitungszeit für neues Framework
Wilde extbase-/
fluid-Fragestunde
OOP-Vokabular
           auf einen Blick
OOP-Vokabular
                            auf einen Blick
public class Book {
  /** @var string */
  protected $title = '';
    /** @var Author */
    protected $author = NULL;
    public function __construct() {
      $this->title = '(no title)';
    }
    public function __destruct() {
      $this->author = NULL;
    }
    public function setAuthor(Author $author) {
      $this->author = $author;
    }
    public function getAuthor() {
      return $this->author;
    }
…
OOP-Vokabular
                            auf einen Blick
      Klasse
public class Book {
  /** @var string */
  protected $title = '';
    /** @var Author */
    protected $author = NULL;
    public function __construct() {
      $this->title = '(no title)';
    }
    public function __destruct() {
      $this->author = NULL;
    }
    public function setAuthor(Author $author) {
      $this->author = $author;
    }
    public function getAuthor() {
      return $this->author;
    }
…
OOP-Vokabular
                            auf einen Blick
      Klasse
public class Book {        Feld, Membervariable
  /** @var string */
  protected $title = '';
    /** @var Author */
    protected $author = NULL;
    public function __construct() {
      $this->title = '(no title)';
    }
    public function __destruct() {
      $this->author = NULL;
    }
    public function setAuthor(Author $author) {
      $this->author = $author;
    }
    public function getAuthor() {
      return $this->author;
    }
…
OOP-Vokabular
                                                         auf einen Blick
                                   Klasse
                             public class Book {        Feld, Membervariable
                               /** @var string */
                               protected $title = '';
                                 /** @var Author */
                                 protected $author = NULL;
                                 public function __construct() {
Methoden, Memberfunktionen




                                   $this->title = '(no title)';
                                 }
                                 public function __destruct() {
                                   $this->author = NULL;
                                 }
                                 public function setAuthor(Author $author) {
                                   $this->author = $author;
                                 }
                                 public function getAuthor() {
                                   return $this->author;
                                 }
                             …
OOP-Vokabular
                                                         auf einen Blick
                                   Klasse
                             public class Book {        Feld, Membervariable
                               /** @var string */
                               protected $title = '';
                                 /** @var Author */
                                 protected $author = NULL;        Konstruktor
                                 public function __construct() {
Methoden, Memberfunktionen




                                   $this->title = '(no title)';
                                 }
                                 public function __destruct() {
                                   $this->author = NULL;
                                 }
                                 public function setAuthor(Author $author) {
                                   $this->author = $author;
                                 }
                                 public function getAuthor() {
                                   return $this->author;
                                 }
                             …
OOP-Vokabular
                                                         auf einen Blick
                                   Klasse
                             public class Book {        Feld, Membervariable
                               /** @var string */
                               protected $title = '';
                                 /** @var Author */
                                 protected $author = NULL;        Konstruktor
                                 public function __construct() {
Methoden, Memberfunktionen




                                   $this->title = '(no title)';
                                 }                                  Destruktor
                                 public function __destruct() {
                                   $this->author = NULL;
                                 }
                                 public function setAuthor(Author $author) {
                                   $this->author = $author;
                                 }
                                 public function getAuthor() {
                                   return $this->author;
                                 }
                             …
OOP-Vokabular
                                                          auf einen Blick
                                   Klasse
                             public class Book {         Feld, Membervariable
                               /** @var string */
                               protected $title = '';
                                 /** @var Author */
                                 protected $author = NULL;        Konstruktor
                                 public function __construct() {
Methoden, Memberfunktionen




                                   $this->title = '(no title)';
                                 }                                  Destruktor
                                 public function __destruct() {
                                   $this->author = NULL;
                                 }
                                 public function setAuthor(Author $author) {
                                   $this->author = $author;
                                 }
                                 public function getAuthor() {
                                   return $this->author;
                                 }                             Getter
                             …
OOP-Vokabular
                                                          auf einen Blick
                                   Klasse
                             public class Book {         Feld, Membervariable
                               /** @var string */
                               protected $title = '';
                                 /** @var Author */
                                 protected $author = NULL;        Konstruktor
                                 public function __construct() {
Methoden, Memberfunktionen




                                   $this->title = '(no title)';
                                 }                                  Destruktor
                                 public function __destruct() {
                                   $this->author = NULL;
                                 }
                                 public function setAuthor(Author $author) {
                                   $this->author = $author;
                                 }                              Setter
                                 public function getAuthor() {
                                   return $this->author;
                                 }                             Getter
                             …
OOP-Vokabular
                                                          auf einen Blick
                                   Klasse
                             public class Book {         Feld, Membervariable
                               /** @var string */
                               protected $title = '';
                                 /** @var Author */
                                 protected $author = NULL;        Konstruktor
                                 public function __construct() {
Methoden, Memberfunktionen




                                   $this->title = '(no title)';
                                 }                                  Destruktor
                                 public function __destruct() {
                                   $this->author = NULL;
                                 }
                                 public function setAuthor(Author $author) {
                                   $this->author = $author;
                                 }                              Setter            Daten-
                                 public function getAuthor() {                   kapselung
                                   return $this->author;
                                 }                             Getter
                             …
OOP-Vokabular
                                                          auf einen Blick
                                   Klasse
                             public class Book {         Feld, Membervariable
                               /** @var string */
                               protected $title = '';
                                 /** @var Author */
                                 protected $author = NULL;        Konstruktor
                                 public function __construct() {
Methoden, Memberfunktionen




                                   $this->title = '(no title)';
                                 }                                  Destruktor
                                 public function __destruct() {
                                   $this->author = NULL;            Type-Hinting
                                 }
                                 public function setAuthor(Author $author) {
                                   $this->author = $author;
                                 }                              Setter              Daten-
                                 public function getAuthor() {                     kapselung
                                   return $this->author;
                                 }                             Getter
                             …
OOP-Vokabular
                                                          auf einen Blick
                                   Klasse
                             public class Book {         Feld, Membervariable
                               /** @var string */
                               protected $title = '';                              $book = new Book();

                                 /** @var Author */
                                 protected $author = NULL;        Konstruktor
                                 public function __construct() {
Methoden, Memberfunktionen




                                   $this->title = '(no title)';
                                 }                                  Destruktor
                                 public function __destruct() {
                                   $this->author = NULL;            Type-Hinting
                                 }
                                 public function setAuthor(Author $author) {
                                   $this->author = $author;
                                 }                              Setter               Daten-
                                 public function getAuthor() {                      kapselung
                                   return $this->author;
                                 }                             Getter
                             …
OOP-Vokabular
                                                          auf einen Blick
                                   Klasse
                             public class Book {         Feld, Membervariable
                               /** @var string */
                               protected $title = '';                              $book = new Book();

                                 /** @var Author */
                                 protected $author = NULL;        Konstruktor
                                                                                         Book-Instanz,
                                 public function __construct() {                         Referenz auf
Methoden, Memberfunktionen




                                   $this->title = '(no title)';                             Objekt
                                 }                                  Destruktor
                                 public function __destruct() {
                                   $this->author = NULL;            Type-Hinting
                                 }
                                 public function setAuthor(Author $author) {
                                   $this->author = $author;
                                 }                              Setter               Daten-
                                 public function getAuthor() {                      kapselung
                                   return $this->author;
                                 }                             Getter
                             …
Vererbung erlaubt
          Code-Reuse
Vererbung erlaubt
          Code-Reuse



  Book



Paperback   Hardcover
Vererbung erlaubt
          Code-Reuse
            class Book {
              …
              public function getTitle() {
                return $this->title();
              }
                public function setTitle($title) {
                  $this->title = $title;
                }
            }

  Book



Paperback   Hardcover
Vererbung erlaubt
          Code-Reuse
            class Book {
              …
              public function getTitle() {
                return $this->title();
              }
                public function setTitle($title) {
                  $this->title = $title;
                }
            }
                        class Paperback extends Book {
  Book                  }
                          …




Paperback   Hardcover
Vererbung erlaubt
          Code-Reuse
            class Book {
              …
              public function getTitle() {
                return $this->title();
              }
                public function setTitle($title) {
                  $this->title = $title;
                }
            }
                        class Paperback extends Book {
  Book                  }
                          …
                              class Hardcover extends Book {
                                …
                              }



Paperback   Hardcover
Vererbung erlaubt
          Code-Reuse
            class Book {
              …
              public function getTitle() {
                return $this->title();
              }
                public function setTitle($title) {
                  $this->title = $title;
                }
            }
                        class Paperback extends Book {
  Book                  }
                          …
                              class Hardcover extends Book {
                                …
                              }



Paperback   Hardcover                   extends = „ist ein“
Polymorphismus
(Wer ein Buch bestellt, bekomme manchmal auch ein
Taschenbuch oder ein gebundenes Buch geliefert.)
Polymorphismus
(Wer ein Buch bestellt, bekomme manchmal auch ein
Taschenbuch oder ein gebundenes Buch geliefert.)

class Bookshelf {
  …
  public function addBook(Book $book) {
    …
  }
  …
}
Polymorphismus
(Wer ein Buch bestellt, bekomme manchmal auch ein
Taschenbuch oder ein gebundenes Buch geliefert.)

class Bookshelf {
  …
  public function addBook(Book $book) {
    …
  }
  …
}           $ivar = new Bookshelf();
            $domainDrivenDevelopment = new Book();
            $ivar->addBook($domainDrivenDevelopment);
            $harryPotterVolumeOne = new Paperback();
            $ivar->addBook($harryPotterVolumeOne);
            $lordOfTheRings = new Hardcover();
            $ivar->addBook($lordOfTheRings);
Interfaces definieren die nötigen
                       Methoden
Interfaces definieren die nötigen
                       Methoden

 Readable



  Book
Interfaces definieren die nötigen
                       Methoden
            interface Readable {
 Readable   }
              public function turnPage();




  Book
Interfaces definieren die nötigen
                       Methoden
            interface Readable {
 Readable   }
              public function turnPage();




            class Book implements Readable {
  Book        …
              public function turnPage() {
                $this->currentPageNumber += 2;
              }
            }
Interfaces definieren die nötigen
                       Methoden
            interface Readable {
 Readable   }
              public function turnPage();



                       implements = „kann auch“
            class Book implements Readable {
  Book        …
              public function turnPage() {
                $this->currentPageNumber += 2;
              }
            }
1x erben, 1000x implementieren
1x erben, 1000x implementieren



      Book
1x erben, 1000x implementieren
                     Publication



      Book
1x erben, 1000x implementieren
 Readable            Publication



        Book
1x erben, 1000x implementieren
 Readable   Soakable   Publication



        Book
1x erben, 1000x implementieren
 Readable     Soakable             Publication



          Book


 class Book extends Publication
   implements Readable, Soakable
 {
     …
 }
Model,View, Controller (MVC)
Model,View, Controller (MVC)
Model,View, Controller (MVC)
   Controller
 bringt alles zusammen
Model,View, Controller (MVC)
   Controller              Model(s)
 bringt alles zusammen   enthalten die Daten
Model,View, Controller (MVC)
   Controller              Model(s)
 bringt alles zusammen   enthalten die Daten
Model,View, Controller (MVC)
   Controller              Model(s)
 bringt alles zusammen   enthalten die Daten




                              View
                         erzeugt die Ausgabe
Model,View, Controller (MVC)
   Controller              Model(s)
 bringt alles zusammen   enthalten die Daten




                              View
                         erzeugt die Ausgabe
Controller in extbase
Controller in extbase
 NewsController
Controller in extbase
 NewsController   ImportController
Controller in extbase
 NewsController      ImportController

                   1 Controller
                    pro Plugin
                  oder BE-Modul
Controller in extbase
 NewsController      ImportController

   listAction      1 Controller
                    pro Plugin
                  oder BE-Modul
Controller in extbase
 NewsController      ImportController

   listAction      1 Controller
                    pro Plugin
  showAction      oder BE-Modul
Controller in extbase
 NewsController      ImportController

   listAction      1 Controller
                    pro Plugin
  showAction      oder BE-Modul

   editAction
Debugging in fluid



<p>{bookshelves}</p>
<f:debug>{bookshelf}</f:debug>
<f:debug title=“key“>{key}</f:debug>
Formular zum Bearbeiten
Formular zum Bearbeiten
<f:link.action action="edit"
arguments="{bookshelf : bookshelf}">
Edit</f:link.action>
Formular zum Bearbeiten
<f:link.action action="edit"
arguments="{bookshelf : bookshelf}">
Edit</f:link.action>




class Tx_Bookshelf_Controller_BookshelfController {
  /**
!   * @param Tx_Bookshelf_Domain_Model_Bookshelf
$bookshelf the Bookshelf to display
!   */
! public function editAction(
     Tx_Bookshelf_Domain_Model_Bookshelf $bookshelf
  ) {
! ! $this->view->assign('bookshelf', $bookshelf);
! }
Formular zum Bearbeiten
  /**
!   * @param Tx_Bookshelf_Domain_Model_Bookshelf
$bookshelf the Bookshelf to display
!   */
! public function updateAction(
     Tx_Bookshelf_Domain_Model_Bookshelf $bookshelf
  ) {
! ! $this->bookshelfRepository->update($bookshelf);
! ! $this->flashMessageContainer
        ->add('Your Bookshelf was updated.');
! ! $this->redirect('list');
! }
Formular zum Bearbeiten
<f:layout name="default" />
                                Bookshelf/
<f:section name="main">          Edit.html
…

<f:form method="post" action="update" name="bookshelf"
  object="{bookshelf}">

  <f:render partial="Bookshelf/formFields" />
! <f:form.submit value="Save" />
</f:form>

</f:section>
Formular zum Bearbeiten
<f:layout name="default" />
                                Bookshelf/
<f:section name="main">          Edit.html
…

<f:form method="post" action="update" name="bookshelf"
  object="{bookshelf}">

  <f:render partial="Bookshelf/formFields" />
! <f:form.submit value="Save" />
</f:form>

</f:section>
                                                Bookshelf/
                                                Update.html
                                                  fehlt …
Formular zum Bearbeiten
                                       Partials/
                                      Bookshelf/
 <label for="title">
   <f:translate key="…" />
                                    formFields.html
 </label><br />
 <f:form.textbox property="brand" /><br />

 <label …></label><br />
 <f:form.textbox property="height" /><br />

 <label …></label><br />
 <f:form.textbox property="width" /><br />
Formular zum Anlegen
Formular zum Anlegen
<f:link.action action="new">New Bookshelf</f:link.action>
Formular zum Anlegen
<f:link.action action="new">New Bookshelf</f:link.action>




class Tx_Bookshelf_Controller_BookshelfController {
! /**
!   * @param Tx_Bookshelf_Domain_Model_Bookshelf $newBookshelf
!   * @dontvalidate $newBookshelf
!   */
! public function newAction(
     Tx_Bookshelf_Domain_Model_Bookshelf $newBookshelf = NULL
  ) {
! ! $this->view->assign('newBookshelf', $newBookshelf);
! }
Formular zum Anlegen


! /**
!   * @param Tx_Bookshelf_Domain_Model_Bookshelf $newBookshelf
!   */
! public function createAction(
     Tx_Bookshelf_Domain_Model_Bookshelf $newBookshelf
  ) {
! ! $this->bookshelfRepository->add($newBookshelf);
! ! $this->flashMessageContainer
        ->add('Your new Bookshelf was created.');
! ! $this->redirect('list');
! }
Formular zum Anlegen

                                  Bookshelf/
<f:layout name="default" />
                                   New.html
<f:section name="main">

<f:form method="post" action="create" name="newBookshelf"
object="{newBookshelf}">

<f:render partial="Bookshelf/formFields"
arguments="{domainObject:domainObject}" />
<f:form.submit value="Create new" />

</f:form>
</f:section>
Formular zum Anlegen

                                  Bookshelf/
<f:layout name="default" />
                                   New.html
<f:section name="main">

<f:form method="post" action="create" name="newBookshelf"
object="{newBookshelf}">

<f:render partial="Bookshelf/formFields"
arguments="{domainObject:domainObject}" />
<f:form.submit value="Create new" />
                                                  Bookshelf/
</f:form>
</f:section>                                      Create.html
                                                    fehlt …
Link zum Löschen
Link zum Löschen
<f:link.action action="delete"
arguments="{bookshelf : bookshelf}">Delete
</f:link.action>
Link zum Löschen
<f:link.action action="delete"
arguments="{bookshelf : bookshelf}">Delete
</f:link.action>




class Tx_Bookshelf_Controller_BookshelfController {
! /**
!   * @param Tx_Bookshelf_Domain_Model_Bookshelf
$bookshelf the Bookshelf to be deleted
!   */
! public function deleteAction(
     Tx_Bookshelf_Domain_Model_Bookshelf $bookshelf
  ) {
! ! $this->bookshelfRepository->remove($bookshelf);
! ! $this->flashMessageContainer
        ->add('Your Bookshelf was removed.');
! ! $this->redirect('list');
! }
Validierung
    steht im
Model
Validierung
    steht im
Model



class Tx_Bookshelf_Domain_Model_Book {
! /**
!  * @var string $title
!  * @validate NotEmpty
!  */
! protected $title;
Validierung
    steht im
Model

             Tipp:
         Cache leeren!

class Tx_Bookshelf_Domain_Model_Book {
! /**
!  * @var string $title
!  * @validate NotEmpty
!  */
! protected $title;
Repositories

Dependency Injection

     Singletons
„Es kann nur
einen geben“
„Es kann nur
einen geben“




Singleton
„Es kann nur
einen geben“



      Interface
   t3lib_Singleton



Singleton
Injection
Dependency
   Injection
Dependency
                                                Injection
class Tx_Bookshelf_Controller_BookshelfController {
! /**
!   * @param Tx_Bookshelf_Domain_Repository_BookshelfRepository $repository
!   */
! public function injectBookshelfRepository(
       Tx_Bookshelf_Domain_Repository_BookshelfRepository $repository
   ) {
! ! $this->bookshelfRepository = $repository
! }
Hollywood-Prinzip:
                                                        „Don‘t call us …
                                                         we‘ll call you.“



                                             Dependency
                                                Injection
class Tx_Bookshelf_Controller_BookshelfController {
! /**
!   * @param Tx_Bookshelf_Domain_Repository_BookshelfRepository $repository
!   */
! public function injectBookshelfRepository(
       Tx_Bookshelf_Domain_Repository_BookshelfRepository $repository
   ) {
! ! $this->bookshelfRepository = $repository
! }
Repositories bringen einiges mit
Repositories bringen einiges mit
findByUid($uid) findOneByUid($uid)
Repositories bringen einiges mit
findByUid($uid) findOneByUid($uid)   findAll()
Repositories bringen einiges mit
findByUid($uid) findOneByUid($uid)   findAll()


findBy*($value)

findByName($name)
findByStatus($status)
Repositories bringen einiges mit
findByUid($uid) findOneByUid($uid)   findAll()


findBy*($value)

findByName($name)
findByStatus($status)


findOneBy*($value)

findOneByName($name)
findOneByIsbn($isbn)
Repositories bringen einiges mit
findByUid($uid) findOneByUid($uid)   findAll()


findBy*($value)

findByName($name)
findByStatus($status)


findOneBy*($value)

findOneByName($name)
findOneByIsbn($isbn)


countBy($value)

countByBrand($brand)
countByStatus($status)
Queries in Repositories benutzen

! /**
!   * @param integer $serviceUid   the service UID
!   * @param string $mobileNumber the mobile number
!   *
!   * @return Tx_Extbase_Persistence_QueryResult result
!   */
! public function findByMobileApplication(
      $serviceUid, $mobileNumber
  ) {
! ! $query = $this->createQuery();
! ! $query->matching($query->logicalAnd(
! ! ! $query->equals('service', $serviceUid),
! ! ! $query->equals('mobile', $mobileNumber)
! ! ));
! ! return $query->execute();
! }
Queries in Repositories benutzen

!   /**
!     * @param integer $serviceUid   the service UID
!     * @param string $mobileNumber the mobile number
!     *
!     * @return Tx_Foo_Domain_Model_Thing the query result
!     */
!   public function findOneByMobileApplication(
!   ! $serviceUid, $mobileNumber
!   ) {
!   ! $query = $this->createQuery();
!   ! $query->matching($query->logicalAnd(
!   ! ! $query->equals('service', $serviceUid),
!   ! ! $query->equals('mobile', $mobileNumber)
!   ! ));
!   ! return $query->execute()->getFirst();
!   }
Queries in Repositories benutzen

!   /**
!    * @param string $phrase
!    *
!    * @return Tx_Extbase_Persistence_QueryResult result
!    */
!   public function findBySearchPhrase($phrase) {
!   ! $query = $this->createQuery();
!   ! $query->matching($query->like(
         'title', '%' . $phrase . '%'
       ));

! ! return $query->execute();
! }
Sortierung
Sortierung



$query = $this->createQuery();
$query->setOrderings(
   array(
      'title' =>
         Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING,
   )
);
Query-Optionen setzen
Query-Optionen setzen

$query = $this->createQuery();
$query->getQuerySettings()->setRespectStoragePage(FALSE);
Query-Optionen setzen

$query = $this->createQuery();
$query->getQuerySettings()->setRespectStoragePage(FALSE);


$query = $this->createQuery();
$query->getQuerySettings()->setEnableFields(FALSE);
Query-Optionen setzen

$query = $this->createQuery();
$query->getQuerySettings()->setRespectStoragePage(FALSE);


$query = $this->createQuery();
$query->getQuerySettings()->setEnableFields(FALSE);


public function initializeObject() {
! $querySettings = $this->objectManager
     ->create('Tx_Extbase_Persistence_Typo3QuerySettings');

! $querySettings->setRespectStoragePage(FALSE);
! $this->setDefaultQuerySettings($querySettings);
}
ViewHelper erstellen
ViewHelper erstellen
                                 HTML-Template
                                  oder Partial
           {namespace bs=Tx_Bookshelf_ViewHelpers}

           <bs:onClick src="{book.image}" />
ViewHelper erstellen
                                 HTML-Template
                                  oder Partial
           {namespace bs=Tx_Bookshelf_ViewHelpers}

           <bs:onClick src="{book.image}" />
ViewHelper erstellen
                                 HTML-Template
                                  oder Partial
           {namespace bs=Tx_Bookshelf_ViewHelpers}

           <bs:onClick src="{book.image}" />
ViewHelper erstellen
                                            HTML-Template
                                             oder Partial
                     {namespace bs=Tx_Bookshelf_ViewHelpers}

                     <bs:onClick src="{book.image}" />



class Tx_Bookshelf_ViewHelpers_OnClickViewHelper extends
Tx_Fluid_Core_ViewHelper_AbstractViewHelper {
! /**
!   * @param string $src
!   * @return string
!   */
! public function render($src) {
     …
  }
ViewHelper mit Inhalt
{namespace bs=Tx_Bookshelf_ViewHelpers}

<bs:acronym>Der RTE in TYPO3 arbeitet
mit ExtJS.</bs:acronym>
                                          HTML-Template
                                           oder Partial
ViewHelper mit Inhalt
{namespace bs=Tx_Bookshelf_ViewHelpers}

<bs:acronym>Der RTE in TYPO3 arbeitet
mit ExtJS.</bs:acronym>
                                          HTML-Template
                                           oder Partial


class Tx_Bookshelf_ViewHelpers_AcronymViewHelper extends
Tx_Fluid_Core_ViewHelper_AbstractViewHelper {
! /**
!   * @return string
!   */
! public function render() {
     $innerContent = $this->renderChildren();
     …
  }
Validatoren
class Tx_Bookshelf_Domain_Model_Book {
! /**
!  * @var string $title
!  * @validate StringLength(minimum=5, maximum=99)
!  */
! protected $title;
Validatoren
class Tx_Bookshelf_Domain_Model_Book {
! /**
!  * @var string $title
!  * @validate Tx_Bookshelf_Domain_Validator_TitleValidator
!  */
! protected $title;
Validatoren
class Tx_Bookshelf_Domain_Model_Book {
        Tx_Bookshelf_Domain_Validator_TitleValidator
! /**
  extends Tx_Extbase_Validation_Validator_AbstractValidator {
! /**@var string $title
    *
!   * @validate Tx_Bookshelf_Domain_Validator_TitleValidator
       @param string $value
!   *
    */@return boolean
! protected $title;
    */
! public function isValid($value) {
! ! if (…) {
! ! ! $this->addError(
! ! ! ! 'The title must not contain any palindromes.',
! ! ! ! 1290592925
! ! ! );
! ! ! return FALSE;
! ! }
! ! …
! }
Validatoren
class Tx_Bookshelf_Domain_Validator_BookValidator
! extends Tx_Extbase_Validation_Validator_AbstractValidator {
! /**
!   * @param Tx_Extbase_Model_Book $value
!   * @return boolean
!   */
! public function isValid($value) {
! ! if (…) {
! ! ! $this->addError(
! ! ! ! 'The book must must be yellow.',
! ! ! ! 1290592925
! ! ! );
! ! ! return FALSE;
! ! }
! ! …
! }
Cronjobs und CLI

class Tx_Bookshelf_Service_Cronjob extends tx_scheduler_Task {
! /**
!   * @return boolean always TRUE
!   */
! public function execute() {
! ! $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions']['Bookshelf']
['modules']['Pi1']['controllers']
! ! ! = array('Bookshelf' => array('actions' => array('cron')));
! ! $bootstrap = t3lib_div::makeInstance('Tx_Extbase_Core_Bootstrap');
! ! $result = $bootstrap->run(
! ! ! '',
! ! ! array(
! ! ! ! 'extensionName' => 'Bookshelf',
! ! ! ! 'pluginName' => 'Pi1',
! ! ! )
! ! );

!   !   return TRUE;
    }
}
Cronjobs und CLI

class Tx_Bookshelf_Service_Cronjob extends tx_scheduler_Task {
! /**
!   * @return boolean always TRUE
!   */
! public function execute() {
! ! $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions']['Bookshelf']
['modules']['Pi1']['controllers']
! ! ! = array('Bookshelf' => array('actions' => array('cron')));
! ! $bootstrap = t3lib_div::makeInstance('Tx_Extbase_Core_Bootstrap');
! ! $result = $bootstrap->run(
! ! ! '',
! ! ! array(
! ! ! ! 'extensionName' => 'Bookshelf',
! ! ! ! 'pluginName' => 'Pi1',
! ! ! )
! ! );

!   !   return TRUE;
                                                       kein TS-Setup …
    }
}
AJAX per typenum
myAjax = PAGE
myAjax {
  config …
  typeNum = 123456
  10 = USER_INT
  10 {
     userFunc = tx_extbase_core_bootstrap->run
     extensionName = Bookshelf
     pluginName = Pi1

        switchableControllerActions {
    !   ! Bookshelf {
    !   ! ! 1 = show
    !   ! }
    !   }

    ! persistence =< plugin.tx_bookshelf.persistence
    ! settings =< plugin. tx_bookshelf.settings
    }
}
AJAX per typenum
myAjax = PAGE
myAjax {
  config …                                oder   per eID
  typeNum = 123456
  10 = USER_INT
  10 {
     userFunc = tx_extbase_core_bootstrap->run
     extensionName = Bookshelf
     pluginName = Pi1

        switchableControllerActions {
    !   ! Bookshelf {
    !   ! ! 1 = show
    !   ! }
    !   }

    ! persistence =< plugin.tx_bookshelf.persistence
    ! settings =< plugin. tx_bookshelf.settings
    }
}
AJAX per typenum
myAjax = PAGE
myAjax {
  config …                                oder   per eID
  typeNum = 123456
  10 = USER_INT
  10 {
     userFunc = tx_extbase_core_bootstrap->run
     extensionName = Bookshelf
     pluginName = Pi1

        switchableControllerActions {
    !   ! Bookshelf {                      wird demnächst
    !   ! ! 1 = show                           besser
    !   ! }
    !   }

    ! persistence =< plugin.tx_bookshelf.persistence
    ! settings =< plugin. tx_bookshelf.settings
    }
}

Objektorientierte Programmierung mit extbase und fluid

  • 1.
    Objektorientierte Programmierung mit extbase und fluid 26.-27.01.2011 Oliver Klee, typo3-coding@oliverklee.de
  • 2.
    pibase und extbase sind Frameworks
  • 3.
    pibase und extbase sind Frameworks pibase
  • 4.
    pibase und extbase sind Frameworks pibase extbase
  • 5.
    pibase und extbase sind Frameworks Backport von pibase extbase
  • 6.
    pibase „unterstützt“ hauptsächlich prozeduralen Code
  • 7.
    pibase „unterstützt“ hauptsächlich prozeduralen Code
  • 8.
    tt_news- Hauptklasse pibase „unterstützt“ hauptsächlich prozeduralen Code
  • 9.
    tt_news- Hauptklasse pibase „unterstützt“ hauptsächlich prozeduralen Code
  • 10.
    tt_news- Hauptklasse pibase „unterstützt“ hauptsächlich prozeduralen Code
  • 11.
    tt_news- Hauptklasse > 400 0 Ze i le n … pibase „unterstützt“ hauptsächlich prozeduralen Code
  • 12.
    Monster- Klassen
  • 13.
    extbase fördert lesbaren, gut wartbaren Code
  • 14.
    news2- Hauptklasse extbase fördert lesbaren, gut wartbaren Code
  • 15.
    news2- Hauptklasse extbase fördert lesbaren, gut wartbaren Code
  • 16.
    news2- Hauptklasse c a . 26 0 Ze i le n … extbase fördert lesbaren, gut wartbaren Code
  • 17.
  • 18.
  • 19.
    class Book { … } extbase unterstützt Domain-Driven Design (DDD)
  • 20.
    class Book { … } extbase unterstützt Domain-Driven Design (DDD)
  • 21.
    fluid erlaubt mächtige HTML-Templates
  • 22.
    fluid erlaubt mächtige HTML-Templates <f:for each="{categories}" as="category"> <table class="overview"> <tr> <td> <h1>{category.title}</h1> </td> <td> <f:image src="{category.image}" width="42"/> </td> </tr> </table> </f:for>
  • 23.
    … und pibaseeher nicht. <!-- ###TEMPLATE_LATEST### begin ! This is the template for the latest news, typically displayed on a frontpage --> <div class="news-latest-container"> ! <h2>###LATEST_HEADER###</h2> ! <!-- ###CONTENT### begin ! ! This is the part of the template substituted with the list of news: ! --> ! ! <!-- ###NEWS### begin ! ! ! Template for a single item ! ! --> ! ! ! <div class="news-latest-item"> ! ! ! ! <span class="news-latest-date"><!--###LINK_ITEM###-->###NEWS_DATE### ###NEWS_TIME###<!-- ###LINK_ITEM###--></span> ! ! ! ! <h3><!--###LINK_ITEM###-->###NEWS_TITLE###<!--###LINK_ITEM###--></h3> ! ! ! ! <!--###LINK_ITEM###-->###NEWS_IMAGE###<!--###LINK_ITEM###--> ! ! ! ! ###NEWS_SUBHEADER###<hr class="clearer" /> ! ! ! ! ###CATWRAP_B### ###TEXT_CAT_LATEST### ###NEWS_CATEGORY### ###NEWS_CATEGORY_IMAGE### ###CATWRAP_E### <div class="news-latest-morelink"><!--###LINK_ITEM###-->###MORE###<!--###LINK_ITEM###--></div> ! ! ! </div> ! ! <!-- ###NEWS### end-->!! ! <!-- ###CONTENT### end --> <div class="news-latest-gotoarchive"><!--###LINK_ARCHIVE###-->###GOTOARCHIVE###<!--###LINK_ARCHIVE###--></div> </div> <!-- ###TEMPLATE_LATEST### end -->
  • 24.
  • 25.
    extbase macht vieleseinfacher die Entwicklung geht schneller
  • 26.
    extbase macht vieleseinfacher die Entwicklung geht schneller es ist weniger Code nötig
  • 27.
    extbase macht vieleseinfacher die Entwicklung geht schneller es ist weniger Code nötig Unit-Tests sind einfacher
  • 28.
    extbase macht vieleseinfacher die Entwicklung geht schneller es ist weniger Code nötig Unit-Tests sind einfacher HTML-Templates können mehr
  • 29.
    extbase macht vieleseinfacher die Entwicklung geht schneller es ist weniger Code nötig Unit-Tests sind einfacher HTML-Templates können mehr Einarbeitungszeit für neues Framework
  • 30.
  • 31.
    OOP-Vokabular auf einen Blick
  • 32.
    OOP-Vokabular auf einen Blick public class Book { /** @var string */ protected $title = ''; /** @var Author */ protected $author = NULL; public function __construct() { $this->title = '(no title)'; } public function __destruct() { $this->author = NULL; } public function setAuthor(Author $author) { $this->author = $author; } public function getAuthor() { return $this->author; } …
  • 33.
    OOP-Vokabular auf einen Blick Klasse public class Book { /** @var string */ protected $title = ''; /** @var Author */ protected $author = NULL; public function __construct() { $this->title = '(no title)'; } public function __destruct() { $this->author = NULL; } public function setAuthor(Author $author) { $this->author = $author; } public function getAuthor() { return $this->author; } …
  • 34.
    OOP-Vokabular auf einen Blick Klasse public class Book { Feld, Membervariable /** @var string */ protected $title = ''; /** @var Author */ protected $author = NULL; public function __construct() { $this->title = '(no title)'; } public function __destruct() { $this->author = NULL; } public function setAuthor(Author $author) { $this->author = $author; } public function getAuthor() { return $this->author; } …
  • 35.
    OOP-Vokabular auf einen Blick Klasse public class Book { Feld, Membervariable /** @var string */ protected $title = ''; /** @var Author */ protected $author = NULL; public function __construct() { Methoden, Memberfunktionen $this->title = '(no title)'; } public function __destruct() { $this->author = NULL; } public function setAuthor(Author $author) { $this->author = $author; } public function getAuthor() { return $this->author; } …
  • 36.
    OOP-Vokabular auf einen Blick Klasse public class Book { Feld, Membervariable /** @var string */ protected $title = ''; /** @var Author */ protected $author = NULL; Konstruktor public function __construct() { Methoden, Memberfunktionen $this->title = '(no title)'; } public function __destruct() { $this->author = NULL; } public function setAuthor(Author $author) { $this->author = $author; } public function getAuthor() { return $this->author; } …
  • 37.
    OOP-Vokabular auf einen Blick Klasse public class Book { Feld, Membervariable /** @var string */ protected $title = ''; /** @var Author */ protected $author = NULL; Konstruktor public function __construct() { Methoden, Memberfunktionen $this->title = '(no title)'; } Destruktor public function __destruct() { $this->author = NULL; } public function setAuthor(Author $author) { $this->author = $author; } public function getAuthor() { return $this->author; } …
  • 38.
    OOP-Vokabular auf einen Blick Klasse public class Book { Feld, Membervariable /** @var string */ protected $title = ''; /** @var Author */ protected $author = NULL; Konstruktor public function __construct() { Methoden, Memberfunktionen $this->title = '(no title)'; } Destruktor public function __destruct() { $this->author = NULL; } public function setAuthor(Author $author) { $this->author = $author; } public function getAuthor() { return $this->author; } Getter …
  • 39.
    OOP-Vokabular auf einen Blick Klasse public class Book { Feld, Membervariable /** @var string */ protected $title = ''; /** @var Author */ protected $author = NULL; Konstruktor public function __construct() { Methoden, Memberfunktionen $this->title = '(no title)'; } Destruktor public function __destruct() { $this->author = NULL; } public function setAuthor(Author $author) { $this->author = $author; } Setter public function getAuthor() { return $this->author; } Getter …
  • 40.
    OOP-Vokabular auf einen Blick Klasse public class Book { Feld, Membervariable /** @var string */ protected $title = ''; /** @var Author */ protected $author = NULL; Konstruktor public function __construct() { Methoden, Memberfunktionen $this->title = '(no title)'; } Destruktor public function __destruct() { $this->author = NULL; } public function setAuthor(Author $author) { $this->author = $author; } Setter Daten- public function getAuthor() { kapselung return $this->author; } Getter …
  • 41.
    OOP-Vokabular auf einen Blick Klasse public class Book { Feld, Membervariable /** @var string */ protected $title = ''; /** @var Author */ protected $author = NULL; Konstruktor public function __construct() { Methoden, Memberfunktionen $this->title = '(no title)'; } Destruktor public function __destruct() { $this->author = NULL; Type-Hinting } public function setAuthor(Author $author) { $this->author = $author; } Setter Daten- public function getAuthor() { kapselung return $this->author; } Getter …
  • 42.
    OOP-Vokabular auf einen Blick Klasse public class Book { Feld, Membervariable /** @var string */ protected $title = ''; $book = new Book(); /** @var Author */ protected $author = NULL; Konstruktor public function __construct() { Methoden, Memberfunktionen $this->title = '(no title)'; } Destruktor public function __destruct() { $this->author = NULL; Type-Hinting } public function setAuthor(Author $author) { $this->author = $author; } Setter Daten- public function getAuthor() { kapselung return $this->author; } Getter …
  • 43.
    OOP-Vokabular auf einen Blick Klasse public class Book { Feld, Membervariable /** @var string */ protected $title = ''; $book = new Book(); /** @var Author */ protected $author = NULL; Konstruktor Book-Instanz, public function __construct() { Referenz auf Methoden, Memberfunktionen $this->title = '(no title)'; Objekt } Destruktor public function __destruct() { $this->author = NULL; Type-Hinting } public function setAuthor(Author $author) { $this->author = $author; } Setter Daten- public function getAuthor() { kapselung return $this->author; } Getter …
  • 44.
  • 45.
    Vererbung erlaubt Code-Reuse Book Paperback Hardcover
  • 46.
    Vererbung erlaubt Code-Reuse class Book { … public function getTitle() { return $this->title(); } public function setTitle($title) { $this->title = $title; } } Book Paperback Hardcover
  • 47.
    Vererbung erlaubt Code-Reuse class Book { … public function getTitle() { return $this->title(); } public function setTitle($title) { $this->title = $title; } } class Paperback extends Book { Book } … Paperback Hardcover
  • 48.
    Vererbung erlaubt Code-Reuse class Book { … public function getTitle() { return $this->title(); } public function setTitle($title) { $this->title = $title; } } class Paperback extends Book { Book } … class Hardcover extends Book { … } Paperback Hardcover
  • 49.
    Vererbung erlaubt Code-Reuse class Book { … public function getTitle() { return $this->title(); } public function setTitle($title) { $this->title = $title; } } class Paperback extends Book { Book } … class Hardcover extends Book { … } Paperback Hardcover extends = „ist ein“
  • 50.
    Polymorphismus (Wer ein Buchbestellt, bekomme manchmal auch ein Taschenbuch oder ein gebundenes Buch geliefert.)
  • 51.
    Polymorphismus (Wer ein Buchbestellt, bekomme manchmal auch ein Taschenbuch oder ein gebundenes Buch geliefert.) class Bookshelf { … public function addBook(Book $book) { … } … }
  • 52.
    Polymorphismus (Wer ein Buchbestellt, bekomme manchmal auch ein Taschenbuch oder ein gebundenes Buch geliefert.) class Bookshelf { … public function addBook(Book $book) { … } … } $ivar = new Bookshelf(); $domainDrivenDevelopment = new Book(); $ivar->addBook($domainDrivenDevelopment); $harryPotterVolumeOne = new Paperback(); $ivar->addBook($harryPotterVolumeOne); $lordOfTheRings = new Hardcover(); $ivar->addBook($lordOfTheRings);
  • 53.
    Interfaces definieren dienötigen Methoden
  • 54.
    Interfaces definieren dienötigen Methoden Readable Book
  • 55.
    Interfaces definieren dienötigen Methoden interface Readable { Readable } public function turnPage(); Book
  • 56.
    Interfaces definieren dienötigen Methoden interface Readable { Readable } public function turnPage(); class Book implements Readable { Book … public function turnPage() { $this->currentPageNumber += 2; } }
  • 57.
    Interfaces definieren dienötigen Methoden interface Readable { Readable } public function turnPage(); implements = „kann auch“ class Book implements Readable { Book … public function turnPage() { $this->currentPageNumber += 2; } }
  • 58.
    1x erben, 1000ximplementieren
  • 59.
    1x erben, 1000ximplementieren Book
  • 60.
    1x erben, 1000ximplementieren Publication Book
  • 61.
    1x erben, 1000ximplementieren Readable Publication Book
  • 62.
    1x erben, 1000ximplementieren Readable Soakable Publication Book
  • 63.
    1x erben, 1000ximplementieren Readable Soakable Publication Book class Book extends Publication implements Readable, Soakable { … }
  • 64.
  • 65.
  • 66.
    Model,View, Controller (MVC) Controller bringt alles zusammen
  • 67.
    Model,View, Controller (MVC) Controller Model(s) bringt alles zusammen enthalten die Daten
  • 68.
    Model,View, Controller (MVC) Controller Model(s) bringt alles zusammen enthalten die Daten
  • 69.
    Model,View, Controller (MVC) Controller Model(s) bringt alles zusammen enthalten die Daten View erzeugt die Ausgabe
  • 70.
    Model,View, Controller (MVC) Controller Model(s) bringt alles zusammen enthalten die Daten View erzeugt die Ausgabe
  • 71.
  • 72.
    Controller in extbase NewsController
  • 73.
    Controller in extbase NewsController ImportController
  • 74.
    Controller in extbase NewsController ImportController 1 Controller pro Plugin oder BE-Modul
  • 75.
    Controller in extbase NewsController ImportController listAction 1 Controller pro Plugin oder BE-Modul
  • 76.
    Controller in extbase NewsController ImportController listAction 1 Controller pro Plugin showAction oder BE-Modul
  • 77.
    Controller in extbase NewsController ImportController listAction 1 Controller pro Plugin showAction oder BE-Modul editAction
  • 78.
  • 79.
  • 80.
    Formular zum Bearbeiten <f:link.actionaction="edit" arguments="{bookshelf : bookshelf}"> Edit</f:link.action>
  • 81.
    Formular zum Bearbeiten <f:link.actionaction="edit" arguments="{bookshelf : bookshelf}"> Edit</f:link.action> class Tx_Bookshelf_Controller_BookshelfController { /** ! * @param Tx_Bookshelf_Domain_Model_Bookshelf $bookshelf the Bookshelf to display ! */ ! public function editAction( Tx_Bookshelf_Domain_Model_Bookshelf $bookshelf ) { ! ! $this->view->assign('bookshelf', $bookshelf); ! }
  • 82.
    Formular zum Bearbeiten /** ! * @param Tx_Bookshelf_Domain_Model_Bookshelf $bookshelf the Bookshelf to display ! */ ! public function updateAction( Tx_Bookshelf_Domain_Model_Bookshelf $bookshelf ) { ! ! $this->bookshelfRepository->update($bookshelf); ! ! $this->flashMessageContainer ->add('Your Bookshelf was updated.'); ! ! $this->redirect('list'); ! }
  • 83.
    Formular zum Bearbeiten <f:layoutname="default" /> Bookshelf/ <f:section name="main"> Edit.html … <f:form method="post" action="update" name="bookshelf" object="{bookshelf}"> <f:render partial="Bookshelf/formFields" /> ! <f:form.submit value="Save" /> </f:form> </f:section>
  • 84.
    Formular zum Bearbeiten <f:layoutname="default" /> Bookshelf/ <f:section name="main"> Edit.html … <f:form method="post" action="update" name="bookshelf" object="{bookshelf}"> <f:render partial="Bookshelf/formFields" /> ! <f:form.submit value="Save" /> </f:form> </f:section> Bookshelf/ Update.html fehlt …
  • 85.
    Formular zum Bearbeiten Partials/ Bookshelf/ <label for="title"> <f:translate key="…" /> formFields.html </label><br /> <f:form.textbox property="brand" /><br /> <label …></label><br /> <f:form.textbox property="height" /><br /> <label …></label><br /> <f:form.textbox property="width" /><br />
  • 86.
  • 87.
    Formular zum Anlegen <f:link.actionaction="new">New Bookshelf</f:link.action>
  • 88.
    Formular zum Anlegen <f:link.actionaction="new">New Bookshelf</f:link.action> class Tx_Bookshelf_Controller_BookshelfController { ! /** ! * @param Tx_Bookshelf_Domain_Model_Bookshelf $newBookshelf ! * @dontvalidate $newBookshelf ! */ ! public function newAction( Tx_Bookshelf_Domain_Model_Bookshelf $newBookshelf = NULL ) { ! ! $this->view->assign('newBookshelf', $newBookshelf); ! }
  • 89.
    Formular zum Anlegen !/** ! * @param Tx_Bookshelf_Domain_Model_Bookshelf $newBookshelf ! */ ! public function createAction( Tx_Bookshelf_Domain_Model_Bookshelf $newBookshelf ) { ! ! $this->bookshelfRepository->add($newBookshelf); ! ! $this->flashMessageContainer ->add('Your new Bookshelf was created.'); ! ! $this->redirect('list'); ! }
  • 90.
    Formular zum Anlegen Bookshelf/ <f:layout name="default" /> New.html <f:section name="main"> <f:form method="post" action="create" name="newBookshelf" object="{newBookshelf}"> <f:render partial="Bookshelf/formFields" arguments="{domainObject:domainObject}" /> <f:form.submit value="Create new" /> </f:form> </f:section>
  • 91.
    Formular zum Anlegen Bookshelf/ <f:layout name="default" /> New.html <f:section name="main"> <f:form method="post" action="create" name="newBookshelf" object="{newBookshelf}"> <f:render partial="Bookshelf/formFields" arguments="{domainObject:domainObject}" /> <f:form.submit value="Create new" /> Bookshelf/ </f:form> </f:section> Create.html fehlt …
  • 92.
  • 93.
    Link zum Löschen <f:link.actionaction="delete" arguments="{bookshelf : bookshelf}">Delete </f:link.action>
  • 94.
    Link zum Löschen <f:link.actionaction="delete" arguments="{bookshelf : bookshelf}">Delete </f:link.action> class Tx_Bookshelf_Controller_BookshelfController { ! /** ! * @param Tx_Bookshelf_Domain_Model_Bookshelf $bookshelf the Bookshelf to be deleted ! */ ! public function deleteAction( Tx_Bookshelf_Domain_Model_Bookshelf $bookshelf ) { ! ! $this->bookshelfRepository->remove($bookshelf); ! ! $this->flashMessageContainer ->add('Your Bookshelf was removed.'); ! ! $this->redirect('list'); ! }
  • 95.
    Validierung steht im Model
  • 96.
    Validierung steht im Model class Tx_Bookshelf_Domain_Model_Book { ! /** ! * @var string $title ! * @validate NotEmpty ! */ ! protected $title;
  • 97.
    Validierung steht im Model Tipp: Cache leeren! class Tx_Bookshelf_Domain_Model_Book { ! /** ! * @var string $title ! * @validate NotEmpty ! */ ! protected $title;
  • 99.
  • 100.
  • 101.
    „Es kann nur einengeben“ Singleton
  • 102.
    „Es kann nur einengeben“ Interface t3lib_Singleton Singleton
  • 103.
  • 104.
    Dependency Injection
  • 105.
    Dependency Injection class Tx_Bookshelf_Controller_BookshelfController { ! /** ! * @param Tx_Bookshelf_Domain_Repository_BookshelfRepository $repository ! */ ! public function injectBookshelfRepository( Tx_Bookshelf_Domain_Repository_BookshelfRepository $repository ) { ! ! $this->bookshelfRepository = $repository ! }
  • 106.
    Hollywood-Prinzip: „Don‘t call us … we‘ll call you.“ Dependency Injection class Tx_Bookshelf_Controller_BookshelfController { ! /** ! * @param Tx_Bookshelf_Domain_Repository_BookshelfRepository $repository ! */ ! public function injectBookshelfRepository( Tx_Bookshelf_Domain_Repository_BookshelfRepository $repository ) { ! ! $this->bookshelfRepository = $repository ! }
  • 107.
  • 108.
    Repositories bringen einigesmit findByUid($uid) findOneByUid($uid)
  • 109.
    Repositories bringen einigesmit findByUid($uid) findOneByUid($uid) findAll()
  • 110.
    Repositories bringen einigesmit findByUid($uid) findOneByUid($uid) findAll() findBy*($value) findByName($name) findByStatus($status)
  • 111.
    Repositories bringen einigesmit findByUid($uid) findOneByUid($uid) findAll() findBy*($value) findByName($name) findByStatus($status) findOneBy*($value) findOneByName($name) findOneByIsbn($isbn)
  • 112.
    Repositories bringen einigesmit findByUid($uid) findOneByUid($uid) findAll() findBy*($value) findByName($name) findByStatus($status) findOneBy*($value) findOneByName($name) findOneByIsbn($isbn) countBy($value) countByBrand($brand) countByStatus($status)
  • 113.
    Queries in Repositoriesbenutzen ! /** ! * @param integer $serviceUid the service UID ! * @param string $mobileNumber the mobile number ! * ! * @return Tx_Extbase_Persistence_QueryResult result ! */ ! public function findByMobileApplication( $serviceUid, $mobileNumber ) { ! ! $query = $this->createQuery(); ! ! $query->matching($query->logicalAnd( ! ! ! $query->equals('service', $serviceUid), ! ! ! $query->equals('mobile', $mobileNumber) ! ! )); ! ! return $query->execute(); ! }
  • 114.
    Queries in Repositoriesbenutzen ! /** ! * @param integer $serviceUid the service UID ! * @param string $mobileNumber the mobile number ! * ! * @return Tx_Foo_Domain_Model_Thing the query result ! */ ! public function findOneByMobileApplication( ! ! $serviceUid, $mobileNumber ! ) { ! ! $query = $this->createQuery(); ! ! $query->matching($query->logicalAnd( ! ! ! $query->equals('service', $serviceUid), ! ! ! $query->equals('mobile', $mobileNumber) ! ! )); ! ! return $query->execute()->getFirst(); ! }
  • 115.
    Queries in Repositoriesbenutzen ! /** ! * @param string $phrase ! * ! * @return Tx_Extbase_Persistence_QueryResult result ! */ ! public function findBySearchPhrase($phrase) { ! ! $query = $this->createQuery(); ! ! $query->matching($query->like( 'title', '%' . $phrase . '%' )); ! ! return $query->execute(); ! }
  • 116.
  • 117.
    Sortierung $query = $this->createQuery(); $query->setOrderings( array( 'title' => Tx_Extbase_Persistence_QueryInterface::ORDER_ASCENDING, ) );
  • 118.
  • 119.
    Query-Optionen setzen $query =$this->createQuery(); $query->getQuerySettings()->setRespectStoragePage(FALSE);
  • 120.
    Query-Optionen setzen $query =$this->createQuery(); $query->getQuerySettings()->setRespectStoragePage(FALSE); $query = $this->createQuery(); $query->getQuerySettings()->setEnableFields(FALSE);
  • 121.
    Query-Optionen setzen $query =$this->createQuery(); $query->getQuerySettings()->setRespectStoragePage(FALSE); $query = $this->createQuery(); $query->getQuerySettings()->setEnableFields(FALSE); public function initializeObject() { ! $querySettings = $this->objectManager ->create('Tx_Extbase_Persistence_Typo3QuerySettings'); ! $querySettings->setRespectStoragePage(FALSE); ! $this->setDefaultQuerySettings($querySettings); }
  • 122.
  • 123.
    ViewHelper erstellen HTML-Template oder Partial {namespace bs=Tx_Bookshelf_ViewHelpers} <bs:onClick src="{book.image}" />
  • 124.
    ViewHelper erstellen HTML-Template oder Partial {namespace bs=Tx_Bookshelf_ViewHelpers} <bs:onClick src="{book.image}" />
  • 125.
    ViewHelper erstellen HTML-Template oder Partial {namespace bs=Tx_Bookshelf_ViewHelpers} <bs:onClick src="{book.image}" />
  • 126.
    ViewHelper erstellen HTML-Template oder Partial {namespace bs=Tx_Bookshelf_ViewHelpers} <bs:onClick src="{book.image}" /> class Tx_Bookshelf_ViewHelpers_OnClickViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper { ! /** ! * @param string $src ! * @return string ! */ ! public function render($src) { … }
  • 127.
    ViewHelper mit Inhalt {namespacebs=Tx_Bookshelf_ViewHelpers} <bs:acronym>Der RTE in TYPO3 arbeitet mit ExtJS.</bs:acronym> HTML-Template oder Partial
  • 128.
    ViewHelper mit Inhalt {namespacebs=Tx_Bookshelf_ViewHelpers} <bs:acronym>Der RTE in TYPO3 arbeitet mit ExtJS.</bs:acronym> HTML-Template oder Partial class Tx_Bookshelf_ViewHelpers_AcronymViewHelper extends Tx_Fluid_Core_ViewHelper_AbstractViewHelper { ! /** ! * @return string ! */ ! public function render() { $innerContent = $this->renderChildren(); … }
  • 129.
    Validatoren class Tx_Bookshelf_Domain_Model_Book { !/** ! * @var string $title ! * @validate StringLength(minimum=5, maximum=99) ! */ ! protected $title;
  • 130.
    Validatoren class Tx_Bookshelf_Domain_Model_Book { !/** ! * @var string $title ! * @validate Tx_Bookshelf_Domain_Validator_TitleValidator ! */ ! protected $title;
  • 131.
    Validatoren class Tx_Bookshelf_Domain_Model_Book { Tx_Bookshelf_Domain_Validator_TitleValidator ! /** extends Tx_Extbase_Validation_Validator_AbstractValidator { ! /**@var string $title * ! * @validate Tx_Bookshelf_Domain_Validator_TitleValidator @param string $value ! * */@return boolean ! protected $title; */ ! public function isValid($value) { ! ! if (…) { ! ! ! $this->addError( ! ! ! ! 'The title must not contain any palindromes.', ! ! ! ! 1290592925 ! ! ! ); ! ! ! return FALSE; ! ! } ! ! … ! }
  • 132.
    Validatoren class Tx_Bookshelf_Domain_Validator_BookValidator ! extendsTx_Extbase_Validation_Validator_AbstractValidator { ! /** ! * @param Tx_Extbase_Model_Book $value ! * @return boolean ! */ ! public function isValid($value) { ! ! if (…) { ! ! ! $this->addError( ! ! ! ! 'The book must must be yellow.', ! ! ! ! 1290592925 ! ! ! ); ! ! ! return FALSE; ! ! } ! ! … ! }
  • 133.
    Cronjobs und CLI classTx_Bookshelf_Service_Cronjob extends tx_scheduler_Task { ! /** ! * @return boolean always TRUE ! */ ! public function execute() { ! ! $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions']['Bookshelf'] ['modules']['Pi1']['controllers'] ! ! ! = array('Bookshelf' => array('actions' => array('cron'))); ! ! $bootstrap = t3lib_div::makeInstance('Tx_Extbase_Core_Bootstrap'); ! ! $result = $bootstrap->run( ! ! ! '', ! ! ! array( ! ! ! ! 'extensionName' => 'Bookshelf', ! ! ! ! 'pluginName' => 'Pi1', ! ! ! ) ! ! ); ! ! return TRUE; } }
  • 134.
    Cronjobs und CLI classTx_Bookshelf_Service_Cronjob extends tx_scheduler_Task { ! /** ! * @return boolean always TRUE ! */ ! public function execute() { ! ! $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['extbase']['extensions']['Bookshelf'] ['modules']['Pi1']['controllers'] ! ! ! = array('Bookshelf' => array('actions' => array('cron'))); ! ! $bootstrap = t3lib_div::makeInstance('Tx_Extbase_Core_Bootstrap'); ! ! $result = $bootstrap->run( ! ! ! '', ! ! ! array( ! ! ! ! 'extensionName' => 'Bookshelf', ! ! ! ! 'pluginName' => 'Pi1', ! ! ! ) ! ! ); ! ! return TRUE; kein TS-Setup … } }
  • 135.
    AJAX per typenum myAjax= PAGE myAjax { config … typeNum = 123456 10 = USER_INT 10 { userFunc = tx_extbase_core_bootstrap->run extensionName = Bookshelf pluginName = Pi1 switchableControllerActions { ! ! Bookshelf { ! ! ! 1 = show ! ! } ! } ! persistence =< plugin.tx_bookshelf.persistence ! settings =< plugin. tx_bookshelf.settings } }
  • 136.
    AJAX per typenum myAjax= PAGE myAjax { config … oder per eID typeNum = 123456 10 = USER_INT 10 { userFunc = tx_extbase_core_bootstrap->run extensionName = Bookshelf pluginName = Pi1 switchableControllerActions { ! ! Bookshelf { ! ! ! 1 = show ! ! } ! } ! persistence =< plugin.tx_bookshelf.persistence ! settings =< plugin. tx_bookshelf.settings } }
  • 137.
    AJAX per typenum myAjax= PAGE myAjax { config … oder per eID typeNum = 123456 10 = USER_INT 10 { userFunc = tx_extbase_core_bootstrap->run extensionName = Bookshelf pluginName = Pi1 switchableControllerActions { ! ! Bookshelf { wird demnächst ! ! ! 1 = show besser ! ! } ! } ! persistence =< plugin.tx_bookshelf.persistence ! settings =< plugin. tx_bookshelf.settings } }