tag:blogger.com,1999:blog-48214606663191835822024-02-08T02:23:05.439-08:00PHP AJAX Web DevelopmentTutorials, tips, and resources on PHP Programming by Hendy IrawanHendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.comBlogger25125tag:blogger.com,1999:blog-4821460666319183582.post-13706961444587153772011-06-21T22:05:00.001-07:002011-06-21T22:05:10.527-07:00Installing PHP Development Tools (PDT) Plugin on Eclipse Indigo IDE<div class='posterous_autopost'><p>It’s very simple right now to get the milestone builds of the <b>PHP Developer Tools (PDT)</b> 3 up and running in <b>Eclipse IDE Indigo release</b> (and a significant improvement on the current <b>Helios</b> SR2 release).</p> <p>Pull down a vanilla <b>Eclipse Indigo</b> (just released!), <b>Classic edition</b> or <b>JavaScript edition</b> from <a href="http://www.eclipse.org/downloads/index.php">http://www.eclipse.org/downloads/index.php</a> and <b>install</b>.</p> <p>Once installed, launch Eclipse and navigate to Help-><b>Install new Software</b>.</p> <p>Add the <b>Indigo update site</b> <span style="font-family: courier new,monospace;"><a href="http://download.eclipse.org/releases/indigo">http://download.eclipse.org/releases/indigo</a></span> . This will take sometime to add, let it go for 5 or so minutes.</p> <p>Once the Indigo Update Site is added, add the PDT 3.0 Update Site: <a href="http://download.eclipse.org/tools/pdt/updates/3.0/milestones/" style="font-family: courier new,monospace;">http://download.eclipse.org/tools/pdt/updates/3.0/milestones/</a><span style="font-family: courier new,monospace;"> </span></p> <p>Now, to install simply select PDT Development Tools All in One SDK (leave the others unselected) and click next. The installation process shouldn’t take more than a few minutes. <br /></p><p>(Article copied almost verbatim from <a href="http://aaronbonner.tumblr.com/post/6035060125/installing-pdt-3-on-eclipse-indigo">Aaron Bonner</a>)<br /></p> <p><div class='p_embed p_image_embed'> <img alt="Php-development-tools-pdt-plug" height="464" src="http://posterous.com/getfile/files.posterous.com/phpajaxweb/xjL2a38KVawTEnNd6ECMprj16ojB3cDXo7J1ytRBRPL4DfxiNV9AbOMmOpiM/PHP-development-tools-PDT-plug.png" width="500" /> <img alt="0php-development-tools-pdt-plug" height="464" src="http://posterous.com/getfile/files.posterous.com/phpajaxweb/tbRFrZ1qN6H7zSrtEbV3hc0vhXBBkUWnBtGXlDKiqy1TvrhLoI1K29XxRdfs/0PHP-development-tools-PDT-plug.png" width="500" /> <div class='p_see_full_gallery'><a href="http://phpajaxweb.posterous.com/installing-php-development-tools-pdt-plugin-o">See the full gallery on Posterous</a></div> </div> </p></div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com1tag:blogger.com,1999:blog-4821460666319183582.post-58972355459895078592011-06-21T10:01:00.001-07:002011-06-21T10:32:27.150-07:00Mozilla Firefox 5.0 Web Browser Released<div class="posterous_autopost">
<div class="p_embed p_image_embed">
<a href="http://posterous.com/getfile/files.posterous.com/phpajaxweb/hCTcuk7HqOyrZMRm4idwmejccq5bHvm6qr4CJ4ZxV1zelKwEqPGJkBxUH2L7/firefox5-small_001.png"><img alt="Firefox5-small_001" height="318" src="http://posterous.com/getfile/files.posterous.com/phpajaxweb/gjZURVeDBikSsVzjk58xxAuEC7BZ58ZIBjpBGGPoPVTqlGVSBgPpZLUOAjSR/firefox5-small_001.png.scaled.500.jpg" width="500" /></a> </div>
<br />
As <a href="http://www.h-online.com/news/item/Firefox-5-coming-21-June-1224419.html">expected</a>, the <a href="http://www.mozilla.org/" rel="external" target="_blank"><b>Mozilla</b> Project</a> has released <b>version 5.0 of <a href="http://www.mozilla.com/en-US/firefox/new/" rel="external" target="_blank">Firefox</a>.</b> The <b>update</b> to the <i>open source</i> <b>web browser</b> comes just three months after the project's last major version, <a href="http://www.h-online.com/open/features/What-s-new-in-Firefox-4-0-1212755.html">Firefox 4.0</a>, which suffered a number of delays – Mozilla has <a href="http://www.h-online.com/news/item/Aurora-Firefox-s-new-Dev-Channel-launches-1227984.html">adopted</a> a version model similar to that used by Google for its Chrome browser. <br />
<br />
One of the most important additions in Firefox 5 is support for <a href="https://developer.mozilla.org/en/CSS/CSS_animations" rel="external" target="_blank">CSS animation</a>, a feature that browsers such as Safari have offered for some time. When creating a CSS animation, a developer specifies the animation's duration and name in the CSS rules for the HTML element in question. The <code>@keyframes</code> selector associated with this name is followed by the rules that describe the element's beginning and end points as well as optional intermediate stages.<br />
<span class="pic_right"></span><br />
<br />
The <a href="http://dnt.mozilla.org/" rel="external" target="_blank">Do-Not-Track header</a> preference has been moved "to increase discoverability". On Windows, it can be found under "Tools-&gt;Options-&gt;Privacy", while on Mac OS X, it is under "Firefox-&gt;Preferences-&gt;Privacy". This preference allows users to tell web sites that they don't wish to have their browsing behaviour tracked. Whether a site respects this or not is up to its developers.<br />
<br />
Other changes include improved canvas, JavaScript, memory, and networking performance, as well as updated standards support for HTML5, XHR, MathML, SMIL and canvas. The "desktop environment integration for Linux users" has also been improved. Introduced in previous Firefox Beta updates, the Firefox development channel switcher <a href="http://blog.mozilla.com/channels/2011/06/02/update-on-channel-switcher/" rel="external" target="_blank">has been removed</a>.<br />
<br />
The mobile version of the web browser has also been updated: <a href="http://www.mozilla.com/en-US/mobile/5.0/releasenotes/" rel="external" target="_blank">Firefox 5 for Android</a> is now capable of sending the Do-Not-Track (DNT) header – the developers say that it is "the first mobile web browser" to offer such a feature. It adds support for IPv6, "overflow: scroll" and "overflow: auto" CSS properties, Restartless Add-ons and HTML5 online/offline events. Users can <a href="https://market.android.com/details?id=org.mozilla.firefox" rel="external" target="_blank">download</a> the release from the Android Market.<br />
<br />
More details, including a list of known issues, can be found in the <a href="http://www.mozilla.com/en-US/firefox/5.0/releasenotes/" rel="external" target="_blank">release notes</a>. Firefox 5.0 is available to <a href="http://www.mozilla.com/en-US/firefox/all.html" rel="external" target="_blank">download</a> for Windows, Mac OS X and Linux from the project's web site. Alternatively, users can upgrade to the new versions, either by waiting for the automated update notification or by manually selecting "Check for updates" from the Help Menu. Mozilla encourages users to upgrade to the latest releases as soon as possible.<br />
<br />
Firefox binaries are released under the <a href="http://www.mozilla.com/en/legal/eula/firefox.html" rel="external" target="_blank">Mozilla Firefox End-User Software License Agreement</a> and the source code is released under <a href="http://www.mozilla.org/MPL/" rel="external" target="_blank">disjunctive tri-licensing</a> that includes the Mozilla Public License, GPLv2 and LGPLv2.1.<br />
<br />
An updated web browser is just one step. Learn PHP and AJAX Web Development quickly with <a href="http://www.amazon.com/gp/product/1847197728/ref=as_li_ss_tl?ie=UTF8&tag=phpajaxweb-20&linkCode=as2&camp=217145&creative=399369&creativeASIN=1847197728"><b>AJAX and PHP: Building Modern Web Applications 2nd Edition book</b></a>.<br /> <br />
<br />
<b>Update:</b> Firefox 5 also <a href="http://www.h-online.com/news/item/Firefox-and-Thunderbird-updates-patch-security-holes-1264744.html">addresses a number of security holes</a> in the browser, five of which are rated as "Critical" by Mozilla.<br />
<br />
<span style="font-size: xx-small;"><span style="font-size: xx-small;">Copied almost verbatim from <a href="http://www.h-online.com/open/news/item/Mozilla-releases-Firefox-5-1264703.html">H Online</a></span>, image from <a href="http://news.softpedia.com/news/Download-Firefox-5-Final-for-Linux-207133.shtml" target="_blank">Softpedia</a></span><br />
<a href="http://www.h-online.com/open/news/item/Mozilla-releases-Firefox-5-1264703.html"></a></div>
Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com1tag:blogger.com,1999:blog-4821460666319183582.post-2285448868095875882011-04-05T01:28:00.001-07:002011-04-05T01:28:51.211-07:00Ext Debug Console Not Disabled - Regression Bug in Ext JS 2.3.0<div class='posterous_autopost'>I just got hit by an annoying <b>regression bug</b> in <b>Ext JS 2.3.0</b> (did not occur in Ext JS 2.2.1), that <b>Ext Debug Console</b> (<b>Firebug Lite</b>-lookalike) still pops up when we use:<p />Ext.log(...)<br />Ext.debug.log(...)<br /> console.log(...)<p />These functions should have no visible effect when using <b>ext-all.js</b> (which should <b>disable Ext Debug Console</b>) as opposed to <b>ext-all-debug.js</b> (which contains Ext Debug Console).<p /> However this pre-1.1-beta bug resurfaces in Ext JS 2.3.0.<p />Several alternative solutions:<br /><ol><li>Upgrade to the latest 3.x Ext JS version</li><li>Downgrade to Ext JS 2.2.1</li><li>Remove manually the offending code in ext-all.js</li> <li>Comment all debugging/logging code in your application<br /></li></ol></div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-67015941553039121642010-11-25T20:17:00.001-08:002010-11-25T20:17:10.903-08:00Referential Integrity - Good or Bad?<div class='posterous_autopost'>In relational database world such as MySQL, PostgreSQL, Derby / JavaDB, and HSQLDB RDBMS there is Referential Integrity. <p /> It's very useful to avoid consistency mistakes with foreign keys during operation. <p /> It's useful when we live in *relational* world. But during development of a modular application and agile, frequent upgrades.. Is referential integrity helping or hindering productivity? <p /> Consider an application that has a Customer table that has a column an refers to a Country table. Each deployment would have its own Customer table data. However, Country table is pretty much "shared" globally. Country table is never meant to be modified from the admin's perspective. <p /> When there is a new country or modification, new version of application will be released, containing an update to Country table. <p /> In old-school style of upgrades, Country table should be replaceable similar to how we replace files during upgrade, i.e. overwriting a file called countries.xml. <p /> However, due to referential integrity, it's not possible to simply drop the table, recreate it with the data. We have to issue proper DML SQL statements to update the data from the "current" version (yes, we must detect what is the current version) to the new version. <p /> All in the name of not breaking foreign key checks aka referential integrity. <p /> Isn't RDBMS making simple things complex?</div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-68237200502994833612010-11-05T23:54:00.001-07:002010-11-05T23:54:00.668-07:00Displaying PHP Errors on Ubuntu<div class='posterous_autopost'>Default <b>configuration</b> of <b>PHP 5.3</b> / <b>Apache</b> <b>2.2</b> installation on <b>Ubuntu</b> <b>10.10 Maverick</b> Meerkat does not display any <b>syntax errors</b> and simply throws an <b>Internal Server Error (HTTP Error 500)</b>.<br /> <div class="gmail_quote"><div><div class="h5"><br /><b>How to</b> <b>enable display/output of PHP 5 error messages</b> :<br /><ol><li>Edit <span style="font-family: courier new,monospace;">/etc/php5/apache2/php.ini</span></li> <li><span style="font-family: courier new,monospace;"></span>Set the following <b>configuration</b> values:<p /><span style="font-family: courier new,monospace;">display_errors = on</span><br style="font-family: courier new,monospace;" /> <span style="font-family: courier new,monospace;">display_startup_errors = on</span><br style="font-family: courier new,monospace;" /><span style="font-family: courier new,monospace;">html_errors = on</span><p /></li><li> The default error_reporting threshold is :<p /><span style="font-family: courier new,monospace;">error_reporting = E_ALL & ~E_DEPRECATED</span><p />which should be enough. But you can change it if you want.<br /></li> </ol></div></div><br /> </div></div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-21701390052168513402010-10-28T20:01:00.001-07:002010-10-28T20:01:20.577-07:00var_export bug Fatal error: Nesting level too deep - recursive dependency? [Workaround]<div class='posterous_autopost'> When doing <b>var_export()</b> on nested arrays/objects with recursive dependency, you'll get an error:<p /> <b>Fatal error: Nesting level too deep - recursive dependency? in /some/script.php on line 123</b><p /> The workaround is:<p /> <tt>ob_start();</tt><br /> <tt>var_dump($data);</tt><br /> <tt>$dataDump = ob_get_clean();</tt><p /> Bug report (but is incorrectly marked as Bogus): <a href="http://bugs.php.net/bug.php?id=30471">http://bugs.php.net/bug.php?id=30471</a> </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com1tag:blogger.com,1999:blog-4821460666319183582.post-34461194622812362442010-10-28T06:21:00.001-07:002010-10-28T06:21:39.631-07:00Dependency Injection in PHP vs Java<div class='posterous_autopost'> How to do <b>Dependency Injection</b> in <b>PHP</b> vs <b>Java</b>.<p /> <b>Plain PHP:</b><p /> <tt>$helper_sales = new HelperSales();</tt><p /> <b><a href="http://www.magentocommerce.com/knowledge-base/entry/magento-for-dev-part-2-the-magento-config/">Magento proprietary SPI</a>:</b><p /> <tt>// no type information!</tt><br /> <tt>$helper_sales = Mage::helper('sales');</tt><p /> <b>Java / CDI :</b><p /> <tt>@Inject</tt><br /> <tt>private HelperSales helperSales;</tt><p /> <b>Java / get bean from Spring context :</b><p /> <tt>HelperSales helperSales = appCtx.getBean(HelperSales.class);</tt><p /> The Java examples apply to Scala as well, of course.<p /> Still envy PHP? </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-28167156514834671462010-10-24T11:38:00.001-07:002010-10-24T11:38:19.434-07:00Displaying AJAX Tables in PHP vs Java EE: ZFDataGrid and PrimeFaces DataTable<div class='posterous_autopost'> While developing with <b>PHP + Zend Framework + Doctrine</b> I missed an easy way to display/edit data using a <b>grid/table</b>.<p /> A very useful component I found is <b><a href="http://code.google.com/p/zfdatagrid/">ZFDataGrid</a></b>.<p /> Here's a sample code of how to use <b>ZFDataGrid:</b><p /> <tt> function simpleAction()</tt> <p /> <tt> {</tt> <tt> //Zend_Config</tt> <tt> $config = new Zend_Config_Ini('./application/grids/grid.ini', 'production');</tt> <tt> </tt> <tt> //Grid Initialization</tt> <tt> $grid = Bvb_Grid::factory('Bvb_Grid_Deploy_Table', $config, 'id');</tt> <tt> </tt> <tt> //Setting grid source</tt> <tt> $grid->setSource(new Bvb_Grid_Source_Zend_Table(new Bugs()));</tt> <tt> </tt> <tt> //CRUD Configuration</tt> <tt> $form = new Bvb_Grid_Form();</tt> <tt> $form->setAdd(true)->setEdit(true)->setDelete(true);</tt> <tt> $grid->setForm($form);</tt> <tt> </tt> <tt> //Pass it to the view</tt> <tt> $this->view->pages = $grid;</tt> <tt> $this->render('index');</tt> <tt> }</tt> <br /> It looks pretty good too.<p /> <a href='http://posterous.com/getfile/files.posterous.com/phpajaxweb/SvEjZbMKirTUR4urKxtC32vNT55ymlsTkXD74VS47LCQ9mbrjgiK7nnB8qMG/zfdatagrid.png'><img src="http://posterous.com/getfile/files.posterous.com/phpajaxweb/NfKbT4C5fCC8JZffIgFwWffYwD3srvtFjiIq84CuSeGrep9853ipTmHOrM86/zfdatagrid.png.scaled.500.jpg" width="500" height="240"/></a> <p /> Check the <b><a href="http://zfdatagrid.com/grid/">ZFDataGrid Live Demo here</a></b>.<p /> However, working with data grids using <b>JSF 2.0</b> and <b>PrimeFaces</b> felt much more natural and easier.<p /> Here's a sample code using <b>PrimeFaces' DataTable </b>:<p /> <tt><h:form></tt><p /> <tt> <p:dataTable var="car" value="#{tableBean.lazyModel}" paginator="true" rows="10" lazy="true"</tt><br /> <tt> paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"</tt><br /> <tt> rowsPerPageTemplate="5,10,15"</tt><br /> <tt> selection="#{tableBean.selectedCar}" selectionMode="single"</tt><br /> <tt> onRowSelectComplete="carDialog.show()" onRowSelectUpdate="display"></tt><br /> <tt> <f:facet name="header"></tt><br /> <tt> Displaying 100,000,000 Cars</tt><br /> <tt> </f:facet></tt><br /> <tt> <p:column headerText="Model"></tt><br /> <tt> <h:outputText value="#{car.model}" /></tt><br /> <tt> </p:column></tt><br /> <tt> <p:column headerText="Year"></tt><br /> <tt> <h:outputText value="#{car.year}" /></tt><br /> <tt> </p:column></tt><br /> <tt> <p:column headerText="Manufacturer"></tt><br /> <tt> <h:outputText value="#{car.manufacturer}" /></tt><br /> <tt> </p:column></tt><br /> <tt> <p:column headerText="Color"></tt><br /> <tt> <h:outputText value="#{car.color}" /></tt><br /> <tt> </p:column></tt><br /> <tt> </p:dataTable></tt><p /> <tt> <p:dialog header="Car Detail" widgetVar="carDialog" resizable="false"</tt><br /> <tt> width="200" showEffect="explode" hideEffect="explode"></tt><br /> <tt> <h:panelGrid id="display" columns="2" cellpadding="4"></tt><br /> <tt> <f:facet name="header"></tt><br /> <tt> <p:graphicImage value="/images/cars/#{tableBean.selectedCar.manufacturer}.jpg"/></tt><br /> <tt> </f:facet></tt><br /> <tt> <h:outputText value="Model:" /></tt><br /> <tt> <h:outputText value="#{tableBean.selectedCar.model}"/></tt><p /> <tt> <h:outputText value="Year:" /></tt><br /> <tt> <h:outputText value="#{tableBean.selectedCar.year}"/></tt><p /> <tt> <h:outputText value="Manufacturer:" /></tt><br /> <tt> <h:outputText value="#{tableBean.selectedCar.manufacturer}"/></tt><p /> <tt> <h:outputText value="Color:" /></tt><br /> <tt> <h:outputText value="#{tableBean.selectedCar.color}"/></tt><br /> <tt> </h:panelGrid></tt><br /> <tt> </p:dialog></tt><p /> <tt></h:form></tt><p /> The above code may look verbose, but it packs a lot of functionality and it's very easy and intuitive to customize.<br /> When you click a row it displays a nice dialog with a picture. Furthermore, it's actually <b>lazy loading 100,000,000 rows</b>!! (yes, ONE HUNDRED MILLION ROWS)<p /> Here's how it looks:<p /> <a href='http://posterous.com/getfile/files.posterous.com/phpajaxweb/4hqGuTGHiLDt9JFiJwBYOkUw02Z6yjqzVJHYXz0st7xy2FBGi9OcA9VsAE3e/primefaces-datatable-lazy-load.png'><img src="http://posterous.com/getfile/files.posterous.com/phpajaxweb/U1fha5zORZdLYlGBfX11uEhneOLKsIkbOqMzG3Heefai6sorphOq7t4dLsrB/primefaces-datatable-lazy-load.png.scaled.500.jpg" width="500" height="229"/></a> <p /> You can see for real the <b><a href="http://www.primefaces.org/showcase/ui/datatableLazy.jsf">PrimeFaces DataTable Lazy-loading Live Demo here</a></b>.<p /> It's very easy to add <b>lazy-loading support to DataTable:</b><p /> <tt> lazyModel = new LazyDataModel<Car>() {</tt><p /> <tt> /**</tt><br /> <tt> * Dummy implementation of loading a certain segment of data.</tt><br /> <tt> * In a real application, this method should load data from a datasource</tt><br /> <tt> */</tt><br /> <tt> @Override</tt><br /> <tt> public List<Car> load(int first, int pageSize, String sortField, boolean sortOrder, Map<String,String> filters) {</tt><br /> <tt> logger.log(Level.INFO, "Loading the lazy car data between {0} and {1}", new Object[]{first, (first+pageSize)});</tt><p /> <tt> //Sorting and Filtering information are not used for demo purposes just random dummy data is returned</tt><p /> <tt> List<Car> lazyCars = new ArrayList<Car>();</tt><br /> <tt> populateLazyRandomCars(lazyCars, pageSize);</tt><p /> <tt> return lazyCars;</tt><br /> <tt> }</tt><br /> <tt> };</tt><p /> <tt> /**</tt><br /> <tt> * In a real application, this number should be resolved by a projection query</tt><br /> <tt> */</tt><br /> <tt> lazyModel.setRowCount(100000000);</tt><p /> Not to disrespect <b>PHP</b> or <b>ZFDataGrid</b> in anyway (I still need to use them for some of my work), but the experience with JSF 2.0 and PrimeFaces wins hands down. I think it's more <b>because of PrimeFaces</b> than JSF 2.0, but they're such a <b>powerful</b> combo (compared to if you use PrimeFaces with JSF 1.2).<p /> I do hope that PrimeFaces provide a utility class that implements LazyDataModel for a Hibernate/HQL or JPA/JPQL query, but for now I can live with the above. </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-31999341907187384782010-10-24T09:59:00.003-07:002010-10-24T09:59:56.083-07:00Fix CDATA Bug on WordPress 3.0.1's WXR Export<div class='posterous_autopost'> Today I migrated one of my client's <b>website from <a href="http://wordpress.org/">WordPress</a> 3.0.1 to <a href="http://drupal.org/">Drupal</a> CMS 6.19.</b><p /> I used WordPress's <b>export</b> function to create a <b>WXR backup/dump file</b> and <b>imported</b> it to Drupal using <a href="http://drupal.org/project/wordpress_import">WordPress Import module</a>.<p /> Unfortunately the <b>WXR export file is unreadable/broken because it is non well-formed.</b><p /> Some investigation reveals that WordPress export doesn't escape CDATA content properly, i.e. content containing "]]>" is left unescaped.<p /> <tt>]]></tt><p /> should be escaped as<p /> <tt>]]]]><![CDATA[></tt><p /> I've reported this bug as <a href="http://core.trac.wordpress.org/ticket/15203">Ticket #15203 on WordPress Trac</a>.<p /> I've also provided a patch as below:<p /> <tt>diff --git a/wp-admin/includes/export.php b/wp-admin/includes/export.php</tt><br /> <tt>index a9e8f22..cd3a9d4 100644</tt><br /> <tt>--- a/wp-admin/includes/export.php</tt><br /> <tt>+++ b/wp-admin/includes/export.php</tt><br /> <tt>@@ -138,6 +138,7 @@ function export_wp( $args = array() ) {</tt><br /> <tt> $str = utf8_encode( $str );</tt><p /> <tt> // $str = ent2ncr(esc_html($str));</tt><br /> <tt>+ $str = str_replace(']]>', ']]]]><![CDATA[>', $str);</tt><br /> <tt> $str = "<![CDATA[$str" . ( ( substr( $str, -1 ) == ']' ) ? ' ' :</tt><p /> <tt> return $str;</tt><p /> <br /> This fixed export functionality. However I think the import functionality is still affected, as it doesn't use a proper XML Parser (see <a href="http://core.trac.wordpress.org/ticket/7400">WordPress Trac Ticket #7400</a>).<p /> With WordPress WXR fixed I can import WordPress contents to Drupal successfully.<p /> P.S. WordPress Import module v6.x-2.1 for Drupal <a href="http://drupal.org/node/736226">fails under PHP 5.3</a>. Solution: Use the latest WordPress import module v6.x-2.x-dev. </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-43157268065023885922010-10-24T09:59:00.001-07:002010-10-24T09:59:35.804-07:00Fix CDATA Bug on WordPress 3.0.1's WXR Export<div class='posterous_autopost'> Today I migrated one of my client's <b>website</b> from <b><a href="http://wordpress.org/">WordPress</a></b> 3.0.1 to <b><a href="http://drupal.org/">Drupal</a> CMS</b> 6.19.<p /> I used WordPress's <b>export</b> function to create a <b>WXR backup/dump file</b> and <b>imported</b> it to Drupal using <a href="http://drupal.org/project/wordpress_import">WordPress Import module</a>.<p /> Unfortunately the WXR file is unreadable because it is non well-formed.<p /> Some investigation reveals that WordPress export doesn't escape CDATA content properly, i.e. content containing "]]>" is left unescaped.<p /> ]]><br /> <blockquote class="posterous_short_quote"> <br /> </blockquote> should be escaped as<p /> <blockquote class="posterous_short_quote"> ]]]]><![CDATA[><p /> </blockquote> I've reported this bug as <a href="http://core.trac.wordpress.org/ticket/15203">Ticket #15203 on WordPress Trac</a>.<p /> I've also provided a patch as below:<p /> <tt>diff --git a/wp-admin/includes/export.php b/wp-admin/includes/export.php</tt><br /> <tt>index a9e8f22..cd3a9d4 100644</tt><br /> <tt>--- a/wp-admin/includes/export.php</tt><br /> <tt>+++ b/wp-admin/includes/export.php</tt><br /> <tt>@@ -138,6 +138,7 @@ function export_wp( $args = array() ) {</tt><br /> <tt> $str = utf8_encode( $str );</tt><br /> <tt> </tt><br /> <tt> // $str = ent2ncr(esc_html($str));</tt><br /> <tt>+ $str = str_replace(']]>', ']]]]><![CDATA[>', $str);</tt><br /> <tt> $str = "<![CDATA[$str" . ( ( substr( $str, -1 ) == ']' ) ? ' ' :</tt><br /> <tt> </tt><br /> <tt> return $str;</tt><p /> This fixed export functionality. However I think the import functionality is still affected, as it doesn't use a proper XML Parser (see <a href="http://core.trac.wordpress.org/ticket/7400">WordPress Trac Ticket #7400</a>).<p /> With WordPress WXR fixed I can import WordPress contents to Drupal successfully.<p /> P.S. WordPress Import module v6.x-2.1 for Drupal <a href="http://drupal.org/node/736226">fails under PHP 5.3</a>. Solution: Use the latest WordPress Import module v6.x-2.x-dev. </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-25063344600281249862010-10-10T15:36:00.001-07:002010-10-10T15:36:41.918-07:00Drupal 7.0 beta 1 Released [Announcement]<div class='posterous_autopost'> Our final <b>Drupal 7</b> alpha version was released about three weeks ago. Today, we're proud to announce the <b>first beta version</b> of Drupal 7.x for your further testing and feedback!<p /> The jump between alpha to beta means the following:<p /> <ul> <li>We <i>think</i> that we have resolved all critical data loss and security bugs in Drupal 7. </li><li>We <i>think</i> that our APIs are now frozen enough so that contributed module and theme authors can start (or pick up again) their <a href="http://drupal.org/project/modules?solrsort=sort_title%20asc&text=d7cx&display=table">#D7CX</a> pledges. </li><li>We <i>think</i> that we have caught and fixed most of the problems with the upgrade path. We were able to successfully upgrade a copy of the Drupal.org database to Drupal 7. </li></ul> <br /> That said, we definitely still have some bugs to shake out, and we need <i>your</i> help to find them! Especially new folks who haven't taken Drupal 7 for a spin yet. So please, do so, and let us know what bugs you find in the <a href="http://drupal.org/project/issues/drupal?categories=All">"Drupal core" issue queue</a> (Please <a href="http://drupal.org/project/issues/search/drupal?text=&assigned=&submitted=&participant=&status[]=1&priorities[]=1&priorities[]=4&priorities[]=2&categories[]=bug&version[]=7.x&issue_tags_op=or&issue_tags=">search incoming issues before filing</a>).<p /> <br /> <h2> <b /></h2>What's new? <b><i>Tons</i></b> of stuff! A revamped user interface, a new admin and default core theme, image handling in core, fields (CCK!) in core, module and theme upgrades from within the browser, an automated testing framework with over 24,000 tests, improved security and scalability, revamped database, AJAX, and file systems, jQuery 1.4, jQuery UI 1.8, RDFa, and literally gazillions of other things! Please see <a href="http://drupalcode.org/viewvc/drupal/drupal/CHANGELOG.txt?revision=1.373&view=markup">CHANGELOG.txt</a> for a comprehensive list of <i>all</i> improvements in Drupal 7.<p /> <br /> <h2> <b /></h2>Updating from previous versions The upgrade path from 6.x => 7.x is actually working reasonably well right now. We need people to test this like crazy! Most of the security issues in Drupal 7 have now been addressed, but the beta should still only be installed for testing and new development or working on migration from 6.x. If you are a module or theme developer, and you haven't started porting your modules and themes to 7.x yet, now is the time! Please report anything you find so that we can be sure to support your contributions.<p /> <i>Always make backups of your data and never do testing on your live site. This is to make sure you keep all of your information intact even if something goes wrong.</i><p /> <br /> <h3> <b /></h3>So when does 7.0 get released? The release version of Drupal 7.0 will be ready after (a) there are no more <a href="http://drupal.org/project/issues/search/drupal?version[0]=156281&status[0]=1&status[1]=8&status[2]=13&status[3]=14&priorities[0]=1&categories[0]=bug&categories[1]=task">critical bugs</a> and (b) we've had at least one release candidate (RC) without adding any more issues to the list.<p /> When will that be? Well, it depends entirely on how many people chip in and help out! The more people help, the faster we can find and fix bugs, and the faster 7.0 gets released. The faster 7.0 gets released, the faster we can start adding new features to Drupal 8.0. So help out where you can, and let's make this the best and most solid release of Drupal yet! :)<p /> <br /> <h2> <b /></h2>How do I help test the beta? Start by either installing a new Drupal site or upgrading an existing one running on a previous version (see INSTALL.txt or UPGRADE.txt in the package). When setting up a new site, you can use the <a href="http://drupal.org/project/devel">Development module</a> to generate some test data (content, users, etc) to help you start testing quickly. As with everything still in development, we do not recommend running pre-releases on a live site. Also, always make sure to backup of your data before performing an upgrade or start testing.<p /> <br /> <h3> <b /></h3>New Drupal Users Are you completely (or relatively) new to Drupal? Or do you know just enough to be dangerous? Are you used to working with other content management systems and willing to lend your perspective in improving the way Drupal works? If so, you're a perfect candidate to help with usability testing and improving documentation! As you're going through Drupal 7, take notes on things you find difficult or confusing, and translate those notes into <a href="http://drupal.org/node/add/project_issue/drupal">an issue</a> which will show up in the <a href="http://drupal.org/project/issues/3060">issue tracker</a>. Make sure to be as clear as possible about what the problem was and provide suggestions on how to improve it -- this makes it easier for developers to help!<p /> You can also help by testing the <a href="http://drupal.org/node/540220">D7 Install Guide</a> and noting any mistakes on the <a href="http://drupal.org/node/538054">issue for this</a>.<p /> <br /> <h3> <b /></h3>Testers Do people often congratulate you on your ability to break things? Are you a creative individual who likes to experiment in unconventional ways to see what happens? Do you enjoy looking over other peoples' work and picking nits in order to make it as good as it possibly can be? If any of these apply to you, you could make a great <b>tester</b>! We need testers both to try out different aspects of Drupal itself, as well as take a look at the <a href="http://drupal.org/project/issues/3060">issue queue</a>, checking bugs to see if they're valid and testing patches to verify they work properly. Read more about <a href="http://drupal.org/node/28245">setting up a testing environment</a> and <a href="http://drupal.org/patch/apply">applying patches</a>.<p /> <br /> <h3> <b /></h3>Module and theme developers There is no better way to shake out any lingering bugs with the API and to ensure that your modules and themes will work with the new version of Drupal than to <a href="http://drupal.org/node/224333">update your modules</a> and <a href="http://drupal.org/node/254940">update your themes</a>! Make sure to file any bugs that you find! And try coding some <a href="http://drupal.org/project/issues/search/coder?text=&assigned=&submitted=&participant=&component[]=Upgrade+Routines&issue_tags_op=or&issue_tags=">upgrade routines</a> to help make the process smoother for the next person!<p /> <br /> <h3> <b /></h3>Drupal Ninjas and Ninjas-in-training If you're adept at Drupal hacking, or are eager to learn, a great place to start is with the <a href="http://drupal.org/project/issues/drupal">bug tracker</a> or the <a href="http://drupal.org/project/issues/search/drupal?version[0]=156281&status[0]=8&status[1]=13&status[2]=14">patch queue</a>. Even if you don't have a full solution for a problem, often even a step in the right direction can be enough for another developer to take it home! Read up on <a href="http://drupal.org/patch">how to create patches</a>.<p /> <br /> <h3> <b /></h3>Drupal interface translators The interface strings of Drupal 7.0 are mostly frozen. The days of major changes to the UI strings are over, but we still are changing texts to fix bugs or to lend clarity in the interface. Around release candidate 1, a formal "string freeze" will be declared at which point it should be safe to start translating.<p /> Source: <a href="http://drupal.org/drupal-7.0-beta1">http://drupal.org/drupal-7.0-beta1</a> </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-74413203462056303242010-10-08T04:06:00.001-07:002010-10-08T04:06:32.013-07:00Relational DBMS vs Object-oriented DBMS vs Document-oriented databases issue is moot when you're already using multiple data stores!<div class='posterous_autopost'>The issue of: <p /> 1. Relational databases (RDBMS) e.g. MySQL, PostgreSQL, SQLite, JavaDB, HSQLDB... versus <br />2. Object-Oriented databases (OODBMS) e.g. db4o... versus <br />3. Document-oriented databases e.g. MongoDB, Apache CouchDB... <p /> ...is probably because many developers (including me! :) are not aware that the application is already using multiple data stores at once. <p /> Note: Practically all data stores, except OODBMS, will require some form of roundtrip serialization, object-mapping and code generation to be conveniently usable inside an application, accessible not only via framework/library API but also via domain model objects and classes. <p /> By the way even if you use an OODBMS, if you use features that require specific language support (e.g. Weaving traits and behaviors, like soft deletes, timestampable, nested sets) and the language (e.g. PHP, Java) doesn't support it, you'll still need to do either code generation, manual coding, or be content with dynamic proxying (say goodbye to IDE code hints!) <p /> Why pick just one data store and debate? <p /> A few I have in mind right now is: <p /> 1. Key-value stores. <br />The application INI configuration file. <br />Cache storage, be it file-backed, memcached-backed, or even RDBMS-backed! (you're just abstracting/implementing a key-value store on top of a relational schema). <br />Translation/localization data is sometimes also stored using this store. <br />Web application Session data also uses key-value (though it does automatic de/serialization). <p /> 2. Hierarchical data store / Object store. <br />XML file. <br />A hierarchy of folders, subfolders, and files. <br />In the case of Zend Frameworks's Zend_Config, also INI files. <br />JSON file. <br />YAML file. <br />CSS file (surprising, eh? Though it's only two levels deep.) <br />I think there's no such thing as an "object store". What exists is a data store that acts like an object repository, that does automatic de/serialization of objects, that stores its data in a hierarchical store or content/document store or hybrid. <br />How an object is serialized/its serialization representation (i.e. "should a GeoPoint instance be embedded or linked?") should be specifiable through some form of metadata/configuration/annotations. <br />The object graph, by itself, does not contain sufficient information to be managed as a data store. <p /> 3. Content/Document store. <br />A content store doesn't always restrict a type to a schema. It allows arbitrary properties to be attached to a content node. <br />Some content stores also allow nesting (hierarchical content stores). <br />The filesystem (fixed standard schema), but some filesystems support additional metadata. <br />The node API in Drupal (implemented on top of RDBMS). <br />The EAV tables in Magento (implemented on top of RDBMS). <br />Natively: the JCR (Java Content Repository) in Alfresco & Jackrabbit (Java), MongoDB, Apache CouchDB, Persevere. <p /> 4. Binary/BLOB store. <br />It's basically a key-value store with support for huge values and block/partial access. <br />The filesystem. <br />S3. <p /> 5. Structured markup. <br />HTML. Wiki format. Markdown. Textile. <br />All fits in one string. <p /> 6. Full text index store. <br />Apache Lucene. <br />Zend_Lucene. <p /> 7. Search store. <br />Apache Solr. <br />The search/faceted navigation index in Magento (built on top of RDBMS). <p /> Did I miss something?</div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-74850393176389625682010-10-07T13:37:00.001-07:002010-10-07T13:37:41.485-07:00Diem Content Management Framework: How does it compare to Drupal?<div class='posterous_autopost'> Replying to <i><a href="http://www.aviblock.com/blog/2010/01/04/diem-my-new-cms-of-choice/comment-page-1/">Aviblock's article</a> : <a href="http://www.aviblock.com/blog/2010/01/04/diem-my-new-cms-of-choice/comment-page-1/">Diem, my new CMS of choice</a> :</i> <p /> I’m also very impressed when I found <b><a href="http://diem-project.org">Diem</a> CMF</b>.<p /> I’m a bit torn here, I quite like Drupal, especially due to its popularity and choice of modules.<p /> However looking at the description of Diem it really looks like it fits my “style” as you say it. I haven’t yet worked with Symfony, I only worked with Doctrine + Zend Framework but I already liked the way things work. (and I believe Symfony is much more convenient than Zend Framework)<p /> Drupal’s architecture leaves a lot to be desired… but de facto it’s one of the most popular CMSes nowadays (along with Joomla and WordPress), with lots of PHP developers familiar with it. </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-79528432847028477292010-10-07T03:40:00.001-07:002010-10-07T03:40:23.102-07:00Setelah debugging 3 jam ruwet, ternyata kesalahan terletak pada bug Zend_Loader_Autoload::getClassAutoloader() ! ah, Zend Framework kauuu membuatku...<div class='posterous_autopost'>Setelah debugging 3 jam ruwet, ternyata kesalahan terletak pada bug Zend_Loader_Autoload::getClassAutoloader() ! <p /> ah, Zend Framework kauuu membuatku...</div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-44591458908606341122010-10-06T13:28:00.001-07:002010-10-06T13:28:53.063-07:00For RIA in JavaScript, GWT is the most sane option<div class='posterous_autopost'>I just tried again coding a rich web UI with: <p /> - Dojo (and DojoX and Dijit, including dojox.data) <br />- Ext JS by Sencha (including the data store) <br />- Prototype <p /> The conclusion is: I missed Google GWT. <p /> JavaScript OOP is such a complex beast that pretty much you have to do it by memory: IDE's won't help much (if at all) on this. <p /> Since a GWT app is written in Java programming language, it comes with all the goodies a good Java IDE (Eclipse) can provide, and that is excellent code completion, refactoring, and error checking support. <p /> Other JavaScript toolkits will require an additional "minification" phase. In GWT it's part of the build process: the app is guaranteed to be small & optimized. <p /> Java does have its limits, such as its static-ness. Projects such as DWR can generate Java stubs. But when you play by Java's rules (including autogenerating stubs) you get back the nice IDE features and sometimes easier debugging. Oh joy. :) <p /> For non-RIA type pages though, either jQuery, Dojo Core, or Prototype rocks. (though I am biased to jQuery due to ubiquity)</div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-81341776409640653942010-10-04T14:10:00.001-07:002010-10-04T14:10:34.816-07:00Assemble Route URL inside Zend_Form<div class='posterous_autopost'> If you want to assemble a route URL inside a Zend_Form (or any other object where you don't have access to the URL View Helper), get an instance of the router and call the assemble method like this:<p /> <tt>class Abispulsa_Deposit_Claim extends Zend_Form {</tt><p /> <tt> public function init() {</tt><br /> <tt> $router = Zend_Controller_Front::getInstance()->getRouter();</tt><br /> <tt> $url = $router->assemble(array('module' => 'deposit', 'controller' => 'index', 'action' => 'claim'));</tt><br /> <tt> $this->setAction($url)->setMethod(self::METHOD_POST);</tt><br /> <tt> ...</tt><p /> Hope this is useful. </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-36488151561540624412010-10-03T06:56:00.001-07:002010-10-03T06:56:53.971-07:00Cannot write output to stream ... error on Zend_Log logger<div class='posterous_autopost'> I got a "Cannot write output to stream ..." when using <tt>Zend_Log</tt> and <tt>Zend_Log_Writer_Stream</tt>.<p /> I have been frustrated by this problem for several long hours, and the cause is because I created a new logger instance in a local variable inside a method of a lot objects. If that sounds confusing, this is the example problem:<p /> <div class="CodeRay"> <div class="code"><pre>class Car { public function drive() { $logger = Zend_Log::factory(/*some config*/); ... } }</pre></div> </div> To solve the problem, I had to do this:<p /> <div class="CodeRay"> <div class="code"><pre>class Car { protected static $_logger; protected static function getLogger() { if (!self::$_logger) self::$_logger = Zend_Log::factory(/*some config*/); return self::$_logger; } public function drive() { $logger = self::getLogger(); ... } }</pre></div> </div> <br /> Annoying, but that's the workaround that works. <img src="http://posterous.com/getfile/files.posterous.com/phpajaxweb/P4e3ALc7ZWsMUH8XynaGWBv1c22EQ1lAgDXMVu0ObrhUtFbgwmTIpj9zvqvB/face-smile.png" width="16" height="16"/> If I have the choice I definitely prefer <a href="http://www.slf4j.org/">SLF4J</a>. <img src="http://posterous.com/getfile/files.posterous.com/phpajaxweb/6GeMhf13o8UJXeyoGIUWxxkaSHuvtK3tTyL8DY9MLfuyHxmIWqBiIqSOu96X/face-wink.png" width="16" height="16"/> </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-86374259218702734252010-09-30T02:47:00.001-07:002010-09-30T02:47:20.916-07:00I hate $this and array(...) ! [PHP rant]<div class='posterous_autopost'> <h3> $this-> </h3> <br /> I have no reason to hate the <b>explicit</b> reference to 'self' or 'this' object.<p /> But it shouldn't be repeated everywhere all around the codebase, every single time!<p /> Ruby:<p /> <div class="CodeRay"> <div class="code"><pre>@name = @first_name + ' ' + @last_name</pre></div> </div> <br /> Java:<p /> <div class="CodeRay"> <div class="code"><pre>name = firstName + " " + lastName</pre></div> </div> <br /> PHP:<p /> <div class="CodeRay"> <div class="code"><pre>$this->name = $this->first_name . ' ' . $this->last_name</pre></div> </div> <br /> Unnecessary typing, unnecessary duplication. I should create a shortcut just for typing "<tt>$this-></tt>"<p /> <h3> array(...) </h3> <br /> <tt>array(2, 3, 5)</tt> doesn't look so bad.<p /> But when you're dealing with nested associative arrays (and it's quite common), it doesn't look very good.<p /> <div class="CodeRay"> <div class="code"><pre>$this->_voucher->setOptions(array( 'storeId' => 'voucherStore', 'storeType' => 'dojo.data.ItemFileReadStore', 'storeParams' => array( 'url' => $router->assemble(array('controller' => 'index', 'action' => 'vouchers-for-number', 'mobile_number_id' => 1)), 'clearOnClose' => true), 'dijitParams' => array('searchAttr' => 'title') ));</pre></div> </div> Ruby and JavaScript nails the sweet spot here. As with Scala (on JVM).<p /> Java (the language) is at least as guilty as PHP on this front and much worse hehehe. </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-81411924297119376232010-09-29T12:40:00.001-07:002010-09-29T12:40:42.391-07:00Two code completion 'FAIL's with PHP<div class='posterous_autopost'> Note that _ denotes cursor.<p /> <h3> #1 </h3> <br /> <div class="CodeRay"> <div class="code"><pre>$user = Doctrine_Core::getTable('User')->find(1); $user->_</pre></div> </div> Code completion at this point should return all members of the "<tt>User</tt>" class, but we get nothing!<p /> <h3> #2 </h3> <br /> <div class="CodeRay"> <div class="code"><pre>$logger = Zend_Registry::get('Zend_Log'); $logger->_</pre></div> </div> It should provide a list of <tt>Zend_Log</tt> members, but... nothing!<p /> So... it's not about dynamic typing vs static typing. It's more about type safety but maybe more accurately <i>type awareness</i> or simply <i>type information</i>.<p /> The above probably also holds true with <i>Ruby on Rails</i>. (and it's probably the fault of Rails' super-flexible-dynamic design by nature)<p /> <h3> Compare Cases with Type Information (or sometimes, Type Inference) </h3> <br /> But very rarely heard in Java :<p /> <div class="CodeRay"> <div class="code"><pre>@Inject EntityManager em; ... em->_</pre></div> </div> <br /> You get full code completion above. And even at times when you get a dumb <tt>Object</tt>, you can always typecast to the type you know you want. </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-53310923512551052572010-09-29T02:49:00.001-07:002010-09-29T02:49:51.692-07:00Rendering JSON Data for dojo.data.ItemFileReadStore - Zend Framework<div class='posterous_autopost'> Dojo library has <tt>dojo.data.ItemFileReadStore</tt> and <tt>dojo.data.ItemFileWriteStore</tt> which are convenient defaults for a simple data store.<p /> However you still have to generate the JSON data from the server-side application.<p /> Luckily Zend Framework has an utility to render JSON data to match dojo.data format called <tt>Zend_Dojo_Data</tt> class.<p /> Here's an example usage:<p /> <div class="CodeRay"> <div class="code"><pre> public function vouchersAction() { $this->_helper->layout->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $vouchers = Doctrine_Core::getTable('Voucher')->findAll(Doctrine_Core::HYDRATE_ARRAY); $data = new Zend_Dojo_Data('code', $vouchers, 'title'); header('Content-Type: application/json'); echo $data->toJson(); }</pre></div> </div> </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-50949011577313762782010-09-29T02:46:00.001-07:002010-09-29T02:46:06.788-07:00Disabling layout & view rendering for direct response output in Zend Framework<div class='posterous_autopost'> Sometimes you want to disable default layout & view rendering in Zend Framework, for example to output a JSON response.<p /> The following bolded two lines do the job:<p /> <div class="CodeRay"> <div class="code"><pre> public function vouchersForNumberAction() { $this->_helper->layout->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); ... $data = new Zend_Dojo_Data('code', $vouchers, 'title'); header('Content-Type: application/json'); echo $data->toJson(); }</pre></div> </div> </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-14730365948075162892010-09-29T02:05:00.001-07:002010-09-29T02:05:31.044-07:00Creating a module in a Zend Framework web application<div class='posterous_autopost'> Zend Framework MVC web application request dispatch mechanism is structured in <b>modules</b> (optional), then <b>controllers</b>, and finally <b>actions</b>.<p /> You have to <a href="http://phpajaxweb.blogspot.com/2010/09/enable-modules-in-zend-framework.html">enable module support</a>.<p /> Then to create a module, use <tt>zf create module</tt> command line tool.<p /> <div class="CodeRay"> <div class="code"><pre>$ zf create module deposit Creating the following module and artifacts: /home/ceefour/zendapp/application/modules/deposit/controllers /home/ceefour/zendapp/application/modules/deposit/models /home/ceefour/zendapp/application/modules/deposit/views /home/ceefour/zendapp/application/modules/deposit/views/scripts /home/ceefour/zendapp/application/modules/deposit/views/helpers /home/ceefour/zendapp/application/modules/deposit/views/filters Updating project profile '/home/ceefour/zendapp/.zfproject.xml'</pre></div> </div> <br /> Then you can create controllers, actions, and view templates as usual. </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-15887482552384847762010-09-29T01:42:00.001-07:002010-09-29T01:42:38.348-07:00Enable layout support in Zend Framework<div class='posterous_autopost'> Zend Framework application generated by Zend Tool doesn't support layouts by default.<p /> <h3> <b>Enabling Layout Support using zf Tool</b> </h3> <br /> Run on command line:<p /> <div class="CodeRay"> <div class="code"><pre>zf enable layout</pre></div> </div> <br /> <h3> Enabling Layout Support via application.ini </h3> <br /> Edit <tt>application/configs/application.ini</tt> and add to the <tt>[production]</tt> environment :<p /> <div class="CodeRay"> <div class="code"><pre>resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"</pre></div> </div> </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-18751671890983015942010-09-29T01:39:00.001-07:002010-09-29T01:39:51.213-07:00Enable modules in Zend Framework<div class='posterous_autopost'> After installing zend framework quickstart, I was looking for a solution to enable modules. Finally I found the solution, add the below line to your <tt>application.ini</tt> file<br /> in the <tt>production</tt> environment:<p /> <div class="CodeRay"> <div class="code"><pre>resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"</pre></div> </div> <br /> <a href="http://www.zendworkz.com/2010/08/enable-modules-in-zend-framework.html">Source</a> </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0tag:blogger.com,1999:blog-4821460666319183582.post-81012989125885080422010-09-29T01:37:00.001-07:002010-09-29T01:37:29.535-07:00Developing PHP Web Application with Zend Framework - First thoughts<div class='posterous_autopost'> I've been doing some <a href="http://php.org/">PHP Development</a> with <a href="http://zend.com">Zend Framework</a> using <a href="http://aptana.org">Aptana Studio IDE</a> in the past few weeks.<p /> During the past year or so, my work was primarily with <a href="http://java.sun.com">Java EE</a> / <a href="http://springframework.org">Spring Framework</a> and <a href="http://rubyonrails.org">Ruby on Rails</a>.<p /> So, there have been some differences in experience.<p /> <b>Good things</b> <ul> <li><b>It will work on my hosting.</b> Zend Framework requires PHP 5.2, which most hosting nowadays already support. </li><li><b>Quick setup... that's the PHP project.</b> The framework, not so... </li><li><b>Pretty good manual.</b> The Zend Framework manual is pretty helpful, and comprehensive. It's not extensive or too detailed, but it shows how to do basic tasks. The rest, you still need the Internet and some good luck. </li></ul> <br /> <b>Bad things</b><p /> I think there are more bad things than good things. <ul> <li><b>PHP 5.3 won't be supported... yet.</b> Most hosting has not yet installed PHP 5.3 due to a number of reasons (laziness probably one of them). So, forget Doctrine 2 and functional programming/lambdas/closures. For example, as of 25 Sep 2010 DreamHost still uses PHP 5.2.14. </li><li><b>Insufficient code completion.</b> NetBeans, Eclipse, and IntelliJ IDE have excellent support for Java code completion. In PHP, not so. There is only limited support for code completion, and that's only for PHP and HTML. For INI files, XML, and proprietary data structures (hierarchical associative arrays)... you have to scour the manuals/Internet/tutorials/etc. Same can be said for Ruby on Rails, though. </li><li><b>Zend Framework has a very steep learning curve, and difficult to setup as a full-stack framework.</b> This is more the "feature" of Zend Framework than PHP. Zend Framework is not a Ruby on Rails killer, and will probably never be due to different philosophy. It's fairer to compare Symfony to Ruby on Rails. It's probably fairer to compare Zend Framework to Spring Framework. Comparing Zend Framework to Symfony is like comparing Spring Framework or Java EE to JBoss Seam. However, I can see why <a href="http://www.magentocommerce.com/">Magento Commerce</a> chooses Zend Framework... It's very flexible. I can imagine it's harder to tweak Symfony or Seam to fit your app, but Zend Framework and Spring Framework are built to be tweaked, mix-and-matched. </li><li><b><a href="http://www.doctrine-project.org">Doctrine ORM</a> has to be integrated in manually. </b>This is both a good thing (flexible) and a bad thing (cumbersome). But it's a bad thing for me because I think it should be easy to use Doctrine by default, and also easy to remove it when not needed. I still haven't set up Doctrine "correctly" in my ZF application, I'm too lazy, and that's ZF's fault. Symfony has done a better job at this. </li><li><b>Lack of important view/action helpers.</b> By default, using the FlashMessenger is tedious, since I can only access it via controller and has to pass it to the view. Why not a flashMessenger() view helper by default? </li></ul> I'll post more thoughts later on as I go... </div>Hendyhttp://www.blogger.com/profile/05192845149798446052noreply@blogger.com0