================================ A Joyride to eZ Components beta2 ================================ :Author: Tobias Schlitt :Date: Friday 23 December 2005 9:13:00 am .. contents:: Table of Contents Come with me on a joyride to `eZ systems'`_ hottest product, the eZ Components. While taking this tour with me, you will also learn some of the nice PHP 5 features. You will get an insider's view on beta2 and I will summarize the most significant changes since the beta1_ release. .. _`eZ systems'`: http://ez.no/ .. _beta1: http://ez.no/ezcomponents/news/ez_components_1_0_beta1 Taking a solid Road =================== For our joyride, we will take a solid road: The eZ Components beta2 . Since the beta1 release of the eZ Components, we - the eZ systems developers - have put a lot of effort into making the enterprise PHP plattform usable for early adopters. So, relax and enjoy while I first talk about the global changes being introduced in the beta2 release, which have affected all components. After that I will tell you about two specific components which where modified to be more reliable. Global Changes ============== We introduced some changes which affected all eZ components equally. Most notably, we put a lot of effort into writing good `inline documentation`_ and decided to use *structs* instead of *arrays* whenever applicable. .. _`inline documentation`: /docs/api High Quality Documentation -------------------------- I have to admit that I never wrote that much documentation within a software project, although I always assumed that I did write a lot in previous times. Hence, concerning the eZ components, I promise to you, you will not find one element which is not thoroughly documented. When browsing the code in the online documentation, you will see that there is information available for all *class/method/constant/attribute/property/*. No doubts, the quality standards for the eZ components documentation have been raised from beta1 to beta2 and the complete API docs are now much more structured and complete. Each main class has a clear usage example shipping with its documentation and the different framework elements are well linked, if dependencies exist. Besides that, there is information available about all thrown exceptions and almost all inherited exceptions. Structs instead of Arrays ------------------------- The biggest changes have taken place when it comes to code clean-up and the unification of implementation approaches. This includes the usage of so-called *structs* in favor of arrays. A struct modelled in PHP is basically a class that has only public attributes and a constructor. Doing data storage within structs has four major benefits when compared to the use of arrays: 1. Structs are much more readable than arrays. 2. Structs are fully documentable (not only by using embedded HTML) when working with phpDocumentor_. 3. In cases of emergency, you can extend structs easily to become a real class. 4. Imagine using overloading, then you can even implement automatic value checks into your data structures. An argument against using structs in PHP is usually the speed penalty you encounter when using many classes, but we found that PHP 5.1's OO is fast enough to replace the complex arrays by simple classes . .. _phpDocumentor: http://www.phpdoc.org Component Changes ================= Some of the changes affected only single eZ Components. Although there is a long list of `available components`_, I will concentrate on the modification of two of them, the Translation_ and ConsoleTools_ components. .. _`available components`: /overview .. _Translation: /Translation .. _ConsoleTools: /ConsoleTools Translation ----------- The Translation component reads XML translation definitions (the Qt Linguist format), supports caching of translation contexts and presents you with a class to apply translations to strings. A filter system allows you to transform translation definitions for special use. Derick Rethans added an implementation of the `SPL Iterator`_ interface to allow faster and more convenient looping through translation backend contexts like this:: $contextData ) ?> In beta1 you had to use explicit haveMore() and currentContext() calls to do this. .. _`SPL Iterator`: http://php.net/spl ConsoleTools ------------ The ConsoleTools_ component is a set of classes to do different actions with the console (also called shell). It assists you with printing formated text to the console and can render progress bars, tables as well as status bars and contains a class for parsing command line options. I myself did a lot of work on this package (which I initially created). The idea was basically, to take over the small parts of eZ Publish code that handles console output and put it into a cute API. While desining the API, we had the idea of adding some new stuff to the implementation like the Progressbar and the Table class. I actively used this component in a project already, thus I put much work in getting this package smooth after all. Now, the API is really cool and I very much enjoy using it. One of the most significant changes is a kind of pseudo struct. It is being used in the ezcConsoleOutput class, which allows the output of formated text to the console. A format is defined by a fore- and background color as well as style attributes like bold. Let's take a look of the benefits gained by introducing the pseudo struct. In beta1 you did:: array( 'default' => array( // pseudo format (used when no format given) 'color' => 'green', // green foreground color ), 'success' => array( // define format "success" 'color' => 'white', // white foreground color 'style' => 'bold', // bold font style ), 'failure' => array( // Define format "failur" 'color' => 'black', // black foreground color 'bgcolor' => 'red', // red background color 'style' => 'bold', // bold font style ), ), ?> In eZ Components beta2 you write:: formats->default->color = 'green'; $out->formats->success->color = 'white'; $out->formats->success->style = array( 'bold' ); $out->formats->failure->color = 'red'; $out->formats->failure->style = array( 'bold' ); $out->formats->failure->bgcolor = 'blue'; ?> Much easier, isn't it? What happens here is that in the background, struct (or struct-like) classes are generated on the fly, which automatically validate the provided values. Even nicer is the new interface for the ezcConsoleTable class, which manages the generation of tables on the shell for you. I do not dare to show to you the code of beta1 as it was simply not satisfying. When working on the beta2 version, I sat back and asked myself this basic question: "How would one access the data of a table structure?" The answer was simple: "Through an array!" You will understand when you consider that two-dimensional arrays are simply table structures (presuming that they have indices with int > 0). So far, so good, and I continued asking myself: "How would one access the formating of a table?" The answer was just as simple as before: "Through an object!" Now, the ezcConsoleTable* classes implement one or more of the SPL interfaces to emulate array-like access as demonstrated further below. I heard Marcus Börger talking about SPL and iterators at several conferences. "Interesting stuff", I always thought to myself, but I never really had a concrete use for it ? in the ConsoleTools component I finally got to use them. As software code can say more then a thousand words, let's take a look at the following sample. Please note that rows of ezcConsoleTableinherit the format and alignment from the global default values if no other values have been provided. Furthermore, the cells inherit the row format if they were set to become the default value. Same applies to borderFormat for the rows, which inherits from the global default if not explicitly changed. For demonstration purposes, we create a simple table which is going to look like this. .. image:: ../../images/articles/2005-12-23-joyride-beta2-table_1.gif The implementation of this table with the help of the ConsoleTools component makes up the following code. Please take a look at the inline comments to understand the routines:: content = 'Headline 1'; // Create 3 more cells in row 0 for ( $i = 2; $i < 5; $i++ ) { // Each array-append creates a new ezcConsoleTableCell object // transparently and we can directly access it. $table[0][]->content = "Headline $i"; } $data = array( 1, 2, 3, 4); // Create some more data in the table... foreach ( $data as $value ) { // Create a new row each time and set it's contents to the actual value // In this place we generate rows on the fly, using the array-append syntax // While the cell is explicitly accessed and created automatically $table[][0]->content = $value; } // Set a format to be used for the first table row's border // All other rows have "default" assigned $table[0]->borderFormat = 'headline'; // Set the content format for all cells of the 3rd row to "sum" $table[2]->format = 'sum'; // Print the table, through the output object, we supplied during construction $table->outputTable(); ?> Cool thing, isn't it? Let's look at another sample table so you can better understand how this works. First, I will show the screenshot of the console output to you, then you will see the source code. Again, further explanations are given in the inline comments. .. image:: ../../images/articles/2005-12-23-joyride-beta2-ezcconsoletableexample_2.png :: formats->evenRow->color = 'red'; $out->formats->evenRow->style = array( 'bold' ); $out->formats->oddRow->color = 'blue'; $out->formats->oddRow->style = array( 'bold' ); // Define format schemes for even and odd cells $out->formats->evenCell->color = 'red'; $out->formats->evenCell->style = array( 'negative' ); $out->formats->oddCell->color = 'blue'; $out->formats->oddCell->style = array( 'negative' ); // Create a new table with a width of 60 chars $table = new ezcConsoleTable( $out, 60 ); // Set global cell content alignmengt to right align $table->options->defaultAlign = ezcConsoleTable::ALIGN_CENTER; // Make iteration for a 5x5 table for ( $i = 0; $i < 5; $i ++ ) { for ( $j = 0; $j < 5; $j++ ) { // Fill each table cell with the string ## $table[$i][$j]->content = '##'; if ( $i === $j ) { // On diagonal line set explicit cell format // Choose wether to set the even or odd format $table[$i][$j]->format = $j % 2 == 0 ? 'evenCell' : 'oddCell'; } } // Set global format for even/odd rows // Each cell in this row which was not explicitly touched in the each above // will inherite the format chosen $table[$i]->format = $i % 2 == 0 ? 'evenRow' : 'oddRow'; // Set border format for even/odd rows $table[$i]->borderFormat = $i % 2 == 0 ? 'evenRow' : 'oddRow'; } $table->outputTable(); ?> Conclusion ========== The eZ Components beta2 release is a great milestone we have reached. Now that I started using them in projects, I can say: their API design is very satisfying. Surely, there is still some work to do for the next version, but we are on the right way ? and the way is already quite solid. So, come on, try out our work and give us feedback by commenting this article or posting a message to the eZ Components forum! I'm so curious, what you geeks think :) And thanks for joining the joyride! Resources ========= * eZ Components beta2 release announcement * An Introduction to eZ Components (with installation instructions) * eZ components Documentation * General information page * List of available components * Technical details * Development roadmap * Changelog * Browse the eZ components source code online * Feel free to ask questions about usage in the eZ components forum * Issues of eZ Components development are being discussed in the eZ components developers mailinglist * logos