<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3284671458011514265</id><updated>2012-02-01T23:32:22.887-08:00</updated><category term='worker die'/><category term='email form'/><category term='design patterns'/><category term='cloud platform'/><category term='flash portfolio'/><category term='symfony cloud'/><category term='mvc pattern'/><category term='asynchronous'/><category term='cloud sites symlink'/><category term='google earth iframe shim'/><category term='rsync'/><category term='joomla'/><category term='cloud application'/><category term='critical section'/><category term='truecrypt'/><category term='AJAX'/><category term='block mode cipher'/><category term='storage'/><category term='doUpdate atomic'/><category term='event'/><category term='mime type validation'/><category term='template'/><category term='dwcryptplugin'/><category term='symfony encryption'/><category term='php shell'/><category term='propel lock'/><category term='cookie'/><category term='symfony file validator'/><category term='propel pessimistic offline lock'/><category term='firefox'/><category term='sshfs'/><category term='mime type'/><category term='worker'/><category term='encryption'/><category term='preventdefault'/><category term='cloud session'/><category term='symfony 1.0'/><category term='google earth overlay'/><category term='web design trends'/><category term='ECB'/><category term='adobe reader plugin'/><category term='amazon'/><category term='cloud hosting'/><category term='google earth div'/><category term='propel locking'/><category term='gearmand'/><category term='kmlevent'/><category term='delete job'/><category term='protection'/><category term='row level lock'/><category term='gnupg'/><category term='php magic file'/><category term='dwcrypt plugin'/><category term='rackspace'/><category term='cloud computing'/><category term='google earth div iframe'/><category term='javascript email'/><category term='beanstalkd client disconnect'/><category term='compatibility mode'/><category term='twig'/><category term='cloud'/><category term='email cloaking bug'/><category term='cloud infrastructure'/><category term='IV'/><category term='concurrency'/><category term='thread'/><category term='rackspace cloud sites'/><category term='adobe reader'/><category term='dead letter queue'/><category term='http referer'/><category term='object oriented programming'/><category term='PHP'/><category term='symfony mime'/><category term='poison message'/><category term='file upload mime'/><category term='worker crash'/><category term='block cipher'/><category term='initialization vector'/><category term='gearman'/><category term='twitter'/><category term='php twitter integration'/><category term='IE8'/><category term='poison job'/><category term='atomic operation'/><category term='php fileinfo mime'/><category term='screen issues'/><category term='howto twitter with php'/><category term='beanstalkd'/><category term='symfony'/><category term='symfony plugin'/><category term='symfony 2.0'/><category term='php tweet'/><category term='data'/><category term='locking'/><category term='google earth plugin'/><title type='text'>The Ender Tech</title><subtitle type='html'>The Ender Tech is a blog about website development techniques and technologies with a focus on open source software.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>ndrtek</name><uri>http://www.blogger.com/profile/01779131195591843080</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_ckDnExDhLgc/Ssuw7SZgd4I/AAAAAAAAAAM/e9ipBMcNrwc/S220/IT.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>48</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-497911953302489749</id><published>2010-09-14T14:52:00.000-07:00</published><updated>2010-09-14T16:59:51.013-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='data'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud'/><category scheme='http://www.blogger.com/atom/ns#' term='gnupg'/><category scheme='http://www.blogger.com/atom/ns#' term='protection'/><category scheme='http://www.blogger.com/atom/ns#' term='amazon'/><category scheme='http://www.blogger.com/atom/ns#' term='truecrypt'/><category scheme='http://www.blogger.com/atom/ns#' term='encryption'/><category scheme='http://www.blogger.com/atom/ns#' term='storage'/><category scheme='http://www.blogger.com/atom/ns#' term='rackspace'/><title type='text'>Is Your Data Lost Among the Clouds?</title><content type='html'>&lt;span style="font-weight: bold;"&gt;Within the cloud, I don't know where my data is and I don't care &lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;because I'm protected&lt;/span&gt;. The name of the game is virtualization and just like the software apps on your computer, they don't know where in the computer's memory their data is stored and they don't care as long as it works.&lt;br /&gt;&lt;br /&gt;I hope that my data is within secure facilities, transmitted across secure networks, and stored on secured servers. But I still don't know where or how. I haven't seen the facility. I haven't seen the servers. I have yet to see a VLAN on the private networks. I don't even know their hardware disposal policies. Do they destroy hard drives with issues or simply toss them free for anyone to pick up?&lt;br /&gt;&lt;br /&gt;So then, how do you protect your data in the cloud? Well, as with life, your data is either moving or it's sitting still. These two require two different methods of protection.&lt;br /&gt;&lt;br /&gt;Protecting your data in-transit (moving) requires securing the communication between the endpoints. The common method that every user knows is SSL (HTTPS). This provides a secure connection between the user's browser and the web server. Within the cloud, this same process applies to communication between servers. With servers you can use SSH. With MySQL you can use SSL between the client and server, or between servers if using something like replication.&lt;br /&gt;&lt;br /&gt;Protecting your data at rest (sitting still) requires securing the storage of the data. The storage can be on the cloud server's hard drives, remote block device (Amazon EBS), or even on a file-based storage such as Rackspace Cloud Files or Amazon S3.&lt;br /&gt;&lt;br /&gt;For data while sitting in roughly one place and that is constantly in use like a database, the encryption needs to happen on the fly. TrueCrypt is a common method but be aware there may be a performance penalty or integration issues with virtual servers. Be sure security is a top priority to catch these potential issues early.&lt;br /&gt;&lt;br /&gt;Protecting data that can be wrapped into a single file, such as database backups, can make use of GnuPG. This method is important for protecting your storage on object/file-based storage services like Cloud Files or S3. You can either pipe the data into GnuPG to be encrypted before being stored to a file or feed the file to GnuPG. Then store the encrypted file on your storage service free for them to replicate and transmit through their networks safely.&lt;br /&gt;&lt;br /&gt;You'll still want make sure no sensitive data gets written to disk unencrypted because then you have to scrub the area to make sure it's gone (if you even can). Just because you deleted the file doesn't mean the data doesn't exist. Also, be careful of remote storage services like Amazon EBS. EBS is actually data that is also in transit. The virtual server storage itself may be backed by a remote SAN using an unknown network.&lt;br /&gt;&lt;br /&gt;Vendors don't always want to give the details so who knows, but it doesn't matter all that much if you take the necessary precautions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-497911953302489749?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/497911953302489749/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/09/is-your-data-lost-among-clouds.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/497911953302489749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/497911953302489749'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/09/is-your-data-lost-among-clouds.html' title='Is Your Data Lost Among the Clouds?'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-4472439087998455165</id><published>2010-07-19T17:16:00.000-07:00</published><updated>2010-07-19T17:42:55.767-07:00</updated><title type='text'>Symfony 1.4 Doctrine - Admin Generator - M:M - Many to many relationships</title><content type='html'>After two days of bad googling.. I think I have finally arrived at a solution.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Problem:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Creating M:M relationships in Symfony 1.4 - Doctrine.  These relationships, saving methods, and admin double lists should all be populated.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Solution:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Correct schema&lt;/li&gt;&lt;li&gt;Correct form classes&lt;/li&gt;&lt;li&gt;Modified routing&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Implementation:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;schema.yml&lt;/span&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;Book:&lt;br /&gt;  columns:&lt;br /&gt;    id: { type: integer(4), primary: true, autoincrement: true }&lt;br /&gt;    title: { type: string(100), notnull: true }&lt;br /&gt;  relations:&lt;br /&gt;    Authors:&lt;br /&gt;      class: Author&lt;br /&gt;      local: book_id&lt;br /&gt;      foreign: author_id&lt;br /&gt;      refClass: AuthorBook //link to AuthorBook class (creates list relation)&lt;br /&gt;&lt;br /&gt;Author:&lt;br /&gt;  columns:&lt;br /&gt;    id: { type: integer(4), primary: true, autoincrement: true }&lt;br /&gt;    title: { type: string(100), notnull: true }&lt;br /&gt;  relations:&lt;br /&gt;    Books:&lt;br /&gt;      class: Book&lt;br /&gt;      local: author_id&lt;br /&gt;      foreign: book_id&lt;br /&gt;      refClass: AuthorBook //link to AuthorBook class (creates list relation)&lt;br /&gt;&lt;br /&gt;AuthorBook&lt;br /&gt;  columns:&lt;br /&gt;    author_id: { type: integer(4), primary: true } // foreign link to author&lt;br /&gt;    book_id: { type: integer(4), primary: true } // foreign link to book&lt;br /&gt;    content: { type: clob, notnull: true } // wanted to attach information onto the linking row&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;routing.yml&lt;/span&gt; - modify column field [Array]&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;author_book:&lt;br /&gt;  class: sfDoctrineRouteCollection&lt;br /&gt;  options:&lt;br /&gt;    model:                AuthorBook&lt;br /&gt;    module:               author_book&lt;br /&gt;    prefix_path:          /author_book&lt;br /&gt;    column:               author_id/:book_id // by default it gets generated as Array&lt;br /&gt;    with_wildcard_routes: true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;AuthorForm.class.php&lt;/span&gt; - using sfFormExtraPlugin&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;$this-&gt;widgetSchema['books_list']-&gt;setOption('renderer_class', 'sfWidgetFormSelectDoubleList');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;BookForm.class.php&lt;/span&gt; - using sfFormExtraPlugin&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;$this-&gt;widgetSchema['authors_list']-&gt;setOption('renderer_class', 'sfWidgetFormSelectDoubleList');&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;References:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.doctrine-project.org/documentation/manual/1_0/en/defining-models:relationships:join-table-associations"&gt;http://www.doctrine-project.org/documentation/manual/1_0/en/defining-models:relationships:join-table-associations&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://melikedev.com/2009/12/09/symfony-w-doctrine-saving-many-to-many-mm-relationships/"&gt;http://melikedev.com/2009/12/09/symfony-w-doctrine-saving-many-to-many-mm-relationships/&lt;/a&gt;&lt;br /&gt;"It took several weeks and perusing several different google searches to  piece together enough information to finally get my head around this  process, hopefully this post will save some babies from being punched  due to frustration." - &lt;span style="color: rgb(255, 0, 0);"&gt;Mike Purcell&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forum.symfony-project.org/index.php/m/88120/"&gt;http://forum.symfony-project.org/index.php/m/88120/&lt;/a&gt;&lt;br /&gt;&lt;span class="MsgBodyText"&gt;"I think admin_double_list is not available  anymore in the core since Sf 1.1.&lt;/span&gt;" - &lt;span style="color: rgb(255, 0, 0);"&gt;theredled&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://tohenk.wordpress.com/2009/04/22/using-multiple-primary-keys-in-admin-generator/"&gt;http://tohenk.wordpress.com/2009/04/22/using-multiple-primary-keys-in-admin-generator/&lt;/a&gt;&lt;br /&gt;"I’ve been dealing with this problem for two days now. I’ve found two  solutions (working with symfony 1.4)&lt;br /&gt;1) create a getter for composite primary key and use this ( return  $keypart1.’-’.$keypart2.’-’.$keypart3) and use this in the url…&lt;br /&gt;2) today I’ve found another solution, I’ think it’s better…For you try to change :Array (in the routing settings) to the url  part compound from collumns of your composite primary key …" - &lt;span style="color: rgb(255, 0, 0);"&gt;tomor&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://groups.google.com/group/symfony-users/browse_thread/thread/9c783fc59dc281ae/"&gt;http://groups.google.com/group/symfony-users/browse_thread/thread/9c783fc59dc281ae/&lt;/a&gt;&lt;br /&gt;"I don't think the admin generators support composite foreign keys." - &lt;span style="color: rgb(255, 0, 0);"&gt;Jonathan Wage&lt;/span&gt; (wrong)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-4472439087998455165?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/4472439087998455165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/07/symfony-14-doctrine-admin-generator-mm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/4472439087998455165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/4472439087998455165'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/07/symfony-14-doctrine-admin-generator-mm.html' title='Symfony 1.4 Doctrine - Admin Generator - M:M - Many to many relationships'/><author><name>Carey Hinoki</name><uri>http://www.blogger.com/profile/14192349328683858918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-3084216204674924381</id><published>2010-05-29T11:55:00.000-07:00</published><updated>2010-05-29T12:22:23.928-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='propel lock'/><category scheme='http://www.blogger.com/atom/ns#' term='doUpdate atomic'/><category scheme='http://www.blogger.com/atom/ns#' term='row level lock'/><category scheme='http://www.blogger.com/atom/ns#' term='propel locking'/><category scheme='http://www.blogger.com/atom/ns#' term='propel pessimistic offline lock'/><title type='text'>Simple Database Record Locking - Propel</title><content type='html'>&lt;pre name="code" class="php"&gt;&lt;br /&gt;$c = new Criteria();&lt;br /&gt;$c-&gt;add(InspectionPeer::ID, $ie-&gt;getId());&lt;br /&gt;$c-&gt;add(InspectionPeer::IN_PROCESS, 1);&lt;br /&gt;if(InspectionPeer::doUpdate($c) === 0) {&lt;br /&gt;    //field was not modified therefore it was already 1 and&lt;br /&gt;    //is being handled by another process so skip&lt;br /&gt;    continue;&lt;br /&gt;}&lt;br /&gt;$ie-&gt;setInProcess(1);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Simple record-level locking is achieved by atomically updating a lock field to grab the lock. This is done by updating the field and checking if it was actually locked by return of doUpdate which indicates the number of rows modified If no rows were modified then it returns 0. If you were able to grab the lock, then it returns 1.&lt;br /&gt;&lt;br /&gt;This is important because it avoid the race condition between checking if the lock is free and actually grabbing the lock, which much the same as a typical get-set race condition with regular memory values.&lt;br /&gt;&lt;br /&gt;This form of locking is known as "pessimistic offline" due to the fact that:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;it grabs the lock first instead of only checking afterwards if it has changed&lt;br /&gt;&lt;/li&gt;&lt;li&gt;it actually stores the lock in the database rather than in the DBMS&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-3084216204674924381?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/3084216204674924381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/05/simple-database-record-locking-propel.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/3084216204674924381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/3084216204674924381'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/05/simple-database-record-locking-propel.html' title='Simple Database Record Locking - Propel'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-8423569444916880140</id><published>2010-05-14T20:21:00.000-07:00</published><updated>2010-05-14T20:38:01.112-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='poison message'/><category scheme='http://www.blogger.com/atom/ns#' term='beanstalkd client disconnect'/><category scheme='http://www.blogger.com/atom/ns#' term='beanstalkd'/><category scheme='http://www.blogger.com/atom/ns#' term='poison job'/><title type='text'>Beanstalkd Poison Jobs/Messages</title><content type='html'>Be careful with handling poison jobs/messages in &lt;a href="http://kr.github.com/beanstalkd/"&gt;beanstalkd&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://github.com/kr/beanstalkd/issues#issue/11"&gt;http://github.com/kr/beanstalkd/issues#issue/11&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;Currently when a client disconnects while it has a reserved job, that  job is instantly released onto the front of the queue, without respect  of its remaining TTR.&lt;/blockquote&gt;Particularly:&lt;br /&gt;&lt;blockquote&gt;A job that causes a worker to crash constantly hogs the front of the  queue, blocking subsequent jobs from coming through.&lt;/blockquote&gt;Be sure to set reasonable timeouts, use separate tubes, and add job stats checking on reserves and releases metrics so the job can be properly logged and discarded.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-8423569444916880140?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/8423569444916880140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/05/beanstalkd-poison-jobsmessages.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/8423569444916880140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/8423569444916880140'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/05/beanstalkd-poison-jobsmessages.html' title='Beanstalkd Poison Jobs/Messages'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-5036695568929655589</id><published>2010-04-28T23:32:00.000-07:00</published><updated>2010-04-28T23:37:03.978-07:00</updated><title type='text'>Propel ORM Does Not Cascade Soft Deletes</title><content type='html'>OK... super annoying... if you set the soft_delete flag in your schema for a Propel project, and that table is related to others via a foreign key... those related rows won't be deleted (or soft deleted) if the parent row is deleted.&lt;br /&gt;&lt;br /&gt;Solution? Well, override the delete method and implement the cascade yourself in software... annoying...&lt;br /&gt;&lt;br /&gt;Perhaps this is one of the reason's that Doctrine is taking over... it automatically implements this solution for you.&lt;br /&gt;&lt;br /&gt;Here are some references:&lt;br /&gt;&lt;a href="http://www.blogger.com/goog_166847774"&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://eatmymonkeydust.com/2009/05/doctrine-gotchas-delete-cascade-sofdelete-and-foreigntype/"&gt;http://eatmymonkeydust.com/2009/05/doctrine-gotchas-delete-cascade-sofdelete-and-foreigntype/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.blogger.com/goog_166847776"&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.doctrine-project.org/documentation/manual/1_1/en/defining-models:transitive-persistence"&gt;http://www.doctrine-project.org/documentation/manual/1_1/en/defining-models:transitive-persistence&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-5036695568929655589?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/5036695568929655589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/04/propel-orm-does-not-cascade-soft.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5036695568929655589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5036695568929655589'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/04/propel-orm-does-not-cascade-soft.html' title='Propel ORM Does Not Cascade Soft Deletes'/><author><name>ndrtek</name><uri>http://www.blogger.com/profile/01779131195591843080</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_ckDnExDhLgc/Ssuw7SZgd4I/AAAAAAAAAAM/e9ipBMcNrwc/S220/IT.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-1773218688101283248</id><published>2010-03-17T17:30:00.000-07:00</published><updated>2010-03-18T15:09:35.330-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='symfony'/><category scheme='http://www.blogger.com/atom/ns#' term='IV'/><category scheme='http://www.blogger.com/atom/ns#' term='dwcryptplugin'/><category scheme='http://www.blogger.com/atom/ns#' term='block cipher'/><category scheme='http://www.blogger.com/atom/ns#' term='block mode cipher'/><category scheme='http://www.blogger.com/atom/ns#' term='symfony encryption'/><category scheme='http://www.blogger.com/atom/ns#' term='dwcrypt plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='initialization vector'/><category scheme='http://www.blogger.com/atom/ns#' term='ECB'/><title type='text'>dwCryptPlugin Defaults Not So Secure</title><content type='html'>Thought installing dwCryptPlugin with the defaults to encrypt sensitive data was enough? &lt;span style="font-weight: bold;"&gt;Almost.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The defaults of dwCryptPlugin are 3DES and ECB. 3DES is still "strong enough" yet it is aging. The default block mode ECB is considered inappropriate for all encryption tasks.&lt;br /&gt;&lt;br /&gt;However, dwCryptPlugin doesn't provide the ability to get or set the initialization vector. That works fine for ECB because it isn't used, but doesn't work at all for other block modes like CBC.&lt;br /&gt;&lt;br /&gt;Solutions? Modify dwCryptPlugin, use a PEAR class like Crypt_BlowFish, or use Zend Framework's Zend_Filter_Encrypt (which defaults to CBC). While you're at it, might as well use AES-256 (Rijndael-256) too.&lt;br /&gt;&lt;br /&gt;Here's some more info for the hungry:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://pear.php.net/package/Crypt_Blowfish"&gt;http://pear.php.net/package/Crypt_Blowfish&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://framework.zend.com/manual/en/zend.filter.set.html"&gt;http://framework.zend.com/manual/en/zend.filter.set.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation"&gt;http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Initialization_vector_.28IV.29"&gt;http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Initialization_vector_.28IV.29&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/Advanced_Encryption_Standard"&gt;http://en.wikipedia.org/wiki/Advanced_Encryption_Standard&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-1773218688101283248?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/1773218688101283248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/03/dwcryptplugin-defaults.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/1773218688101283248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/1773218688101283248'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/03/dwcryptplugin-defaults.html' title='dwCryptPlugin Defaults Not So Secure'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-1376596117937144380</id><published>2010-03-02T11:01:00.000-08:00</published><updated>2010-03-02T11:42:41.302-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cookie'/><category scheme='http://www.blogger.com/atom/ns#' term='adobe reader plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='adobe reader'/><category scheme='http://www.blogger.com/atom/ns#' term='http referer'/><title type='text'>Adobe Reader PDF Streaming Referer</title><content type='html'>While maintaining a legacy application that contains Referer header checks we noticed an issue with the loading of PDF files. Saving the PDF files to worked fine but loading them within the browser via the Adobe Reader plugin would not work.&lt;br /&gt;&lt;br /&gt;Turns out that the streaming rendering of Adobe Reader does not send Referer headers on the subsequent requests. From what I could see, it appears that:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The browser makes the request to the server&lt;/li&gt;&lt;li&gt;The server tells the browser that the content type is application/pdf&lt;/li&gt;&lt;li&gt;The browser notifies the Adobe Reader plugin that it has a file to handle&lt;/li&gt;&lt;li&gt;Adobe Reader takes control and makes its own request that accepts partial content responses but doesn't send the Referer header&lt;/li&gt;&lt;/ol&gt;After the initial connection from Firefox succeeded, the rest would fail. Since no Referer was sent at all and this was a simple .htaccess HTTP_REFERER check, it had to be disabled. It is important to note, however, that the Cookie header is sent which is a superior to the Referer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-1376596117937144380?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/1376596117937144380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/03/adobe-reader-pdf-streaming-referer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/1376596117937144380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/1376596117937144380'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/03/adobe-reader-pdf-streaming-referer.html' title='Adobe Reader PDF Streaming Referer'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-8841644342456262770</id><published>2010-02-20T23:49:00.000-08:00</published><updated>2010-03-02T11:01:35.160-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='firefox'/><category scheme='http://www.blogger.com/atom/ns#' term='event'/><category scheme='http://www.blogger.com/atom/ns#' term='IE8'/><category scheme='http://www.blogger.com/atom/ns#' term='kmlevent'/><category scheme='http://www.blogger.com/atom/ns#' term='google earth plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='preventdefault'/><title type='text'>Google Earth Plugin Oddities</title><content type='html'>A couple issues I experienced:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Body tag or plugin div tag need a margin&lt;/li&gt;&lt;li&gt;IE8 (IE7?) cannot test plugin-object properties&lt;/li&gt;&lt;/ul&gt;For some strange reason, in Firefox 3.5.x (maybe 3.5.6 and later?), the Google Earth Plugin would not render if the &lt;span style="font-style: italic;"&gt;body &lt;/span&gt;tag and the plugin container div (commonly "map3d") were both set to &lt;span style="font-style: italic;"&gt;margin: 0;&lt;/span&gt;. You would only see the loading image and that would disappear, yet javascript-wise, everything loaded fine.&lt;br /&gt;&lt;br /&gt;Weirder yet is that if you resized the browser then the plugin would render itself. I tested this on two different computers with no difference. If you give either tag a 1px margin, then the plugin would show up fine.&lt;br /&gt;&lt;br /&gt;In IE8, there was a test: &lt;span style="font-style: italic;"&gt;if(event &amp;amp;&amp;amp; event.preventDefault){} &lt;/span&gt;as a measure of defensive programming. &lt;span style="font-style: italic;"&gt;event&lt;/span&gt; being the native KMLEvent or KMLMouseEvent object mapped into javascript. However, it appears that IE8 either couldn't test, or flat out choked on testing for the &lt;span style="font-style: italic;"&gt;preventDefault&lt;/span&gt; function and thus had to be changed to a simple: &lt;span style="font-style: italic;"&gt;if(event){}. &lt;/span&gt;&lt;span&gt;I'm assuming this is because IE's plugin/javascript is fairly weak and doesn't have the ability to grab properties on mapped objects.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-8841644342456262770?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/8841644342456262770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/02/google-earth-plugin-oddities.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/8841644342456262770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/8841644342456262770'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/02/google-earth-plugin-oddities.html' title='Google Earth Plugin Oddities'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-661467203483066761</id><published>2010-02-16T11:45:00.000-08:00</published><updated>2010-02-16T11:46:32.838-08:00</updated><title type='text'>Finding Competitors Backlinks</title><content type='html'>&lt;p&gt;For people that are new to SEO, they might have no idea how to do some competition analysis. How do you find your competitors backlinks?&lt;br /&gt;The most popular command for finding backlinks is the 'link:' command, which you can use in both Google and Yahoo! Site Explorer. For better in-depth backlink analysis, more people tend to use Yahoo! Site Explorer because it lists more backlinks, whereas Google will only list a small percent.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;In addition to the 'link:' command, you can use many other queries and commands to find references to your competitor links. The following commands may be helpful:&lt;br /&gt;"www.competitorURL.com"&lt;br /&gt;inurl:www.competitorURL.com&lt;br /&gt;inanchor:www.competitorURL.com&lt;br /&gt;intitle:www.competitorURL.com&lt;br /&gt;allintitle:www.competitorURL.com&lt;br /&gt;allintitle:www.competitorURL.com site:.org&lt;br /&gt;site:.edu inanchor:www.competitorURL.com&lt;br /&gt;site:.gov inanchor:www.competitorURL.com&lt;/p&gt;&lt;p&gt;&lt;br /&gt;You can also use variations of these commands. Although some of these commands may not yield backlinks per se, you will at least be able to see where these competitors are mentioned. The more you know about your competition, the better.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-661467203483066761?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/661467203483066761/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/02/finding-competitors-backlinks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/661467203483066761'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/661467203483066761'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/02/finding-competitors-backlinks.html' title='Finding Competitors Backlinks'/><author><name>sonia</name><uri>http://www.blogger.com/profile/04342699327155397193</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-607427971608613709</id><published>2010-01-22T15:39:00.001-08:00</published><updated>2010-01-22T19:45:55.486-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript email'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='thread'/><category scheme='http://www.blogger.com/atom/ns#' term='critical section'/><category scheme='http://www.blogger.com/atom/ns#' term='locking'/><category scheme='http://www.blogger.com/atom/ns#' term='asynchronous'/><category scheme='http://www.blogger.com/atom/ns#' term='atomic operation'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Investigating JavaScript "Concurrency"</title><content type='html'>&lt;span style="font-weight: bold;"&gt;(This article was written with knowledge gained from tests againsts FireFox 3.5 HTML-served JavaScript. I'm interested in input from others on the correctness of this article and their findings. Thanks.)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You may notice that can have JavaScript running while seemingly also handling a UI event or processing the result of an AJAX call. Is it running concurrently? Actually, to a degree, no it isn't.&lt;br /&gt;&lt;br /&gt;When researching this topic, I came across a couple posts that stated "js is single-threaded." Ok, but what does that mean? From my tests, essentially it means that any asynchronous events are only executed after the currently existing script has yielded.&lt;br /&gt;&lt;br /&gt;Does yielding sound familiar? &lt;a href="http://en.wikipedia.org/wiki/Computer_multitasking#Cooperative_multitasking.2Ftime-sharing"&gt;Cooperative multitasking&lt;/a&gt;. The application has to relinquish control for the system to continue. If you ever get stuck in a while-loop the web browser hangs because it never yielded to the UI.&lt;br /&gt;&lt;br /&gt;Nowadays &lt;a href="http://en.wikipedia.org/wiki/Computer_multitasking#Preemptive_multitasking.2Ftime-sharing"&gt;preemptive multitasking&lt;/a&gt; is common. The operating system forcibly removes control at any point within the application. This effectively makes all shared state subject to a race condition. Even if you're simply incrementing a variable that's three operations: get, increment, and store which can be preempted at any point between them.&lt;br /&gt;&lt;br /&gt;JavaScript is a dialect of &lt;a href="http://www.ecmascript.org/"&gt;ECMAScript&lt;/a&gt; (most being &lt;a href="http://www.ecma-international.org/publications/files/ECMA-ST-ARCH/ECMA-262,%203rd%20edition,%20December%201999.pdf"&gt;ECMA-262, Edition 3&lt;/a&gt; compatiable; latest being &lt;a href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf"&gt;Edition 5&lt;/a&gt;). While ECMA-262 says nothing about threads, concurrency, or even atomic operations they can actually exist via extensions -- much like other programming languages that use a library or the operating system to properly handle concurrency.&lt;br /&gt;&lt;br /&gt;But ECMA-262 also says nothing about yielding. So how does this supposedly cooperative multitasking implementation yield?&lt;br /&gt;&lt;br /&gt;Well, from my tests, the global executing block has to end. As soon as that block of execution has reached its end control is given back to the browser to then execute asynchronously scheduled tasks like AJAX calls and UI interactions.&lt;br /&gt;&lt;br /&gt;A simple example is if you schedule a 2-second-long AJAX call within your &amp;lt;script&amp;gt;&amp;lt;/script&amp;gt; block that takes 4-seconds to run, your AJAX event handler will be waiting 2-seconds for its turn to run. The actual AJAX shuffling will occur in its own browser thread but that's outside of JavaScript's scope.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://dev.w3.org/html5/workers/"&gt;W3C Web Workers&lt;/a&gt; is coming onto the scene as a form of "threading" but it's scope is private and you only communicate with it via basic messages. You still probably don't need any locking protection because it communicates just like any other async event -- waiting to be scheduled into execution when others have yielded.&lt;br /&gt;&lt;br /&gt;Maybe one day we'll see &amp;lt;script type=&amp;quot;application/javascript;preempt=true&amp;quot;&amp;gt; in the JavaScript engine's continuing quest for speed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-607427971608613709?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/607427971608613709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/01/investigating-javascript-concurrency.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/607427971608613709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/607427971608613709'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/01/investigating-javascript-concurrency.html' title='Investigating JavaScript &quot;Concurrency&quot;'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-2375592331192812263</id><published>2010-01-14T18:53:00.000-08:00</published><updated>2010-01-14T19:02:24.719-08:00</updated><title type='text'>Admin Generated List and Sorting</title><content type='html'>I noticed that trying to sort a column in an admin generated list causes a white screen of death. I traced it down to the call_user_func_array() function and did a search on google. &lt;br /&gt;&lt;br /&gt;I found this article here &lt;a href="http://forum.symfony-project.org/index.php?t=rview&amp;goto=90728&amp;th=24521"&gt;http://forum.symfony-project.org/index.php?t=rview&amp;goto=90728&amp;th=24521&lt;/a&gt; which is the exact same problem I was having.&lt;br /&gt;&lt;br /&gt;The suggested fix is to add &lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;class_exists($peerclass);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;before&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;return call_user_func_array($callable, $args);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;in the propel/util/BasePeer.php in the getFieldnames() function&lt;br /&gt;&lt;br /&gt;There is another function translateFieldname that also uses the call_user_func_array but I’m not sure if that function needs call_exists($peerclass).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-2375592331192812263?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/2375592331192812263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/01/admin-generated-list-and-sorting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/2375592331192812263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/2375592331192812263'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/01/admin-generated-list-and-sorting.html' title='Admin Generated List and Sorting'/><author><name>Doe</name><uri>http://www.blogger.com/profile/15822071924190395658</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-3577441212826750387</id><published>2010-01-14T09:54:00.000-08:00</published><updated>2010-01-14T10:41:04.160-08:00</updated><title type='text'>Multiple Inserts with Prepared statements in Symfony 1.4</title><content type='html'>I have a symfony 1.4 project in the works and I needed to create a function that would insert 5,000 records into a database.&lt;br /&gt;&lt;br /&gt;In a previous symfony 1.0 project I would typically create a custom query and manually create the SQL statement but I recently just started working with symfony 1.4 and found that they use PDO and from my understanding and experience so far, I couldn't create my custom query that would contain&lt;br /&gt;&lt;br /&gt;What I had to do was create a prepared statement. Here was the basic set up with Propel.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;pre name="code" class="php"&gt;&lt;/span&gt;&lt;br /&gt;$connection = Propel::getConnection();&lt;br /&gt;&lt;br /&gt;$sql = 'INSERT INTO table_1 (name, date) VALUES (:name, :date)';&lt;br /&gt;&lt;br /&gt;$statement = $connection-&gt;prepare($sql);&lt;br /&gt;&lt;br /&gt;foreach ($my_array as $key =&gt; $value) {&lt;br /&gt;  $statement-&gt;bindValue(':name', $value['name']');&lt;br /&gt;  $statement-&gt;bindValue(':date', $value['date']');&lt;br /&gt;  $result = $statement-&gt;execute();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above set up was faster than using a doInsert and inserting by creating an object and using -&gt;save().&lt;br /&gt;&lt;br /&gt;I found that the above setup was able to insert all 5,000 records without timing out where as using doInsert() only inserted ~4,600 records until it timed out.&lt;br /&gt;&lt;br /&gt;Creating an object and using -&gt;save() in a loop was the slowest method. I was able to insert ~3,700 records before it timed out.&lt;br /&gt;&lt;br /&gt;I tested this out several times and was able to replicate the results.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Summary&lt;/span&gt; (Speed of inserting records from fastest to slowest)&lt;br /&gt;1) Prepared statements&lt;br /&gt;2) doInsert()&lt;br /&gt;3) $object-&gt;save()&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Benefits to using a prepared statement (ref: php.net)&lt;/span&gt;&lt;br /&gt;&lt;ul class="itemizedlist"&gt;&lt;li class="listitem"&gt;    &lt;span class="simpara"&gt;     The query only needs to be parsed (or prepared) once, but can be     executed multiple times with the same or different parameters. When the     query is prepared, the database will analyze, compile and optimize it's     plan for executing the query. For complex queries this process can take     up enough time that it will noticeably slow down an application if there     is a need to repeat the same query many times with different parameters. By     using a prepared statement the application avoids repeating the     analyze/compile/optimize cycle. This means that prepared statements use fewer     resources and thus run faster.    &lt;/span&gt;   &lt;/li&gt;&lt;li class="listitem"&gt;    &lt;span class="simpara"&gt;     The parameters to prepared statements don't need to be quoted; the     driver automatically handles this. If an application exclusively uses     prepared statements, the developer can be sure that no SQL injection will     occur (however, if other portions of the query are being built up with     unescaped input, SQL injection is still possible).    &lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-3577441212826750387?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/3577441212826750387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/01/multiple-inserts-with-prepared.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/3577441212826750387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/3577441212826750387'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/01/multiple-inserts-with-prepared.html' title='Multiple Inserts with Prepared statements in Symfony 1.4'/><author><name>Doe</name><uri>http://www.blogger.com/profile/15822071924190395658</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-3773613503236802295</id><published>2010-01-08T11:39:00.000-08:00</published><updated>2010-01-08T11:51:38.910-08:00</updated><title type='text'>Multiple Select &amp; Fillin in Symfony</title><content type='html'>So I came across an annoying issue the other day. I have a select box with multiple select as true in a Symfony 1.0 project with fillin turned on. If I select multiple options in the selectbox and submit the form incomplete so that I have errors, the form re-displays with only the first option I choose selected.&lt;br /&gt;&lt;br /&gt;The title of this blog links to a forum post with the exact same issue. Unfortunately there isn't much feedback on the issue.&lt;br /&gt;&lt;br /&gt;I've tried excluding the field from the validation yml with no success but my field is setup as an array so I'm not sure if I'm excluding it properly.&lt;br /&gt;&lt;br /&gt;I'd appreciate any info/feedback on this issue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-3773613503236802295?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://osdir.com/ml/symfony-users/2009-06/msg00654.html' title='Multiple Select &amp; Fillin in Symfony'/><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/3773613503236802295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/01/multiple-select-fillin-in-symfony.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/3773613503236802295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/3773613503236802295'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/01/multiple-select-fillin-in-symfony.html' title='Multiple Select &amp; Fillin in Symfony'/><author><name>Doe</name><uri>http://www.blogger.com/profile/15822071924190395658</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-7372119646330779523</id><published>2010-01-05T11:06:00.000-08:00</published><updated>2010-01-05T11:35:00.439-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IE8'/><category scheme='http://www.blogger.com/atom/ns#' term='AJAX'/><category scheme='http://www.blogger.com/atom/ns#' term='screen issues'/><category scheme='http://www.blogger.com/atom/ns#' term='compatibility mode'/><title type='text'>IE 8 and Website screen issues.</title><content type='html'>Well I've come across this a couple times on two different sites with two different issues.&lt;br /&gt;&lt;br /&gt;First issue I came across dealt with, I believe it's called, "Infinite Menus" a javascript based menu system. Well in IE8 there were major display issues that would cause the whole menu to overlap one element throwing everything off. The site I was working with was built on Ender Technology's own frame work.&lt;br /&gt;&lt;br /&gt;Second issue I came across was in a site built off the Symfony framework. The issue was that ajax'ed items were not properly resizing it's outer container. So if you ran an ajax function and had it fill a div, the outer container would not resize causing overlapping issues.&lt;br /&gt;&lt;br /&gt;So the fix my colleague and I found was to use the tag shown below in the sites layout.&lt;span id="ctl00_MTCS_main_ctl06"&gt;&lt;pre class="libCScode" style="white-space: pre-wrap;" id="ctl00_MTCS_main_ctl06_code" space="preserve"&gt;&lt;span style="color: blue;"&gt;&lt;&lt;/span&gt;&lt;span style="color: maroon;"&gt;meta&lt;/span&gt; http-equiv="X-UA-Compatible" content="IE=7" &lt;span style="color: blue;"&gt;/&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;The link I provided in this blog points to a more in-depth analysis and use of the tag but it basically sets IE8 browsers to display the site in compatibility mode for whatever version of IE you'd prefer.&lt;br /&gt;&lt;br /&gt;If anyone has any input on the downsides of using this please feel free to contribute.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-7372119646330779523?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://msdn.microsoft.com/en-us/library/cc817574.aspx' title='IE 8 and Website screen issues.'/><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/7372119646330779523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2010/01/ie-8-and-website-screen-issues.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/7372119646330779523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/7372119646330779523'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2010/01/ie-8-and-website-screen-issues.html' title='IE 8 and Website screen issues.'/><author><name>Doe</name><uri>http://www.blogger.com/profile/15822071924190395658</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-276022495963145497</id><published>2009-12-10T16:46:00.000-08:00</published><updated>2009-12-10T16:54:31.865-08:00</updated><title type='text'>IE 6 display problems</title><content type='html'>Because of display issues on a recent project I researched how many people still use IE6. I was not expecting that it still has a user base of about 13%. (Nov. 2009).  Here are some interesting thoughts / reasons why some people cling to IE6. From CSS-tricks.com:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;1. Because they have to (30%)&lt;br /&gt;&lt;br /&gt;I hear fairly regularly from people using IE 6 because that’s what is on their computer at work and they are not allowed to change it. Big companies are slow to change, that has always been true. I’m no security expert, but I’m told IE 7 is a much more secure browser, I would think that alone would be intensive for big companies to get their employees on IE 7. But still, from an IT perspective, I can understand how rolling out a change like this can take tons of man hours for seemingly little benefit, especially if using the web isn’t core to the companies business.&lt;br /&gt;&lt;br /&gt;People might also hold onto IE 6 because they use a website that either does, or claims to, only work on that browser. These websites are getting fewer and far between but they are certainly out there.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2. Because they have an old computer. (20%)&lt;br /&gt;&lt;br /&gt;If they are using Windows 2000 IE 6 is the most current browser for that operating system as far as I know. Not to mention ME and 98.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;3. Because they actively don’t care / dislike change (35%)&lt;br /&gt;&lt;br /&gt;I say “actively” because if they just “passively” don’t care, Windows has probably automatically upgraded them without them even knowing. If they are actively not caring, they are probably clicking “No” and “Cancel” on whatever dialog boxes come up suggesting upgrades. They are probably creating more work for themselves by doing so, but they don’t know that.&lt;br /&gt;&lt;br /&gt;If anything does change on their system, they may even take drastic steps to have it restored to it’s original version. I bet Geek Squad people could tell your stories of people demanding their web browser be returned to IE 6 after accidentally upgrading. People get used to using software in a certain way to get what they need to do done, and they are prone to getting upset if anything interrupts that.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4. Because they don’t know any better (15%)&lt;br /&gt;&lt;br /&gt;I believe this is the smallest portion. People that could or would upgrade to a better browser, if convinced, but just don’t know the advantages yet.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Check out the latest statistics on browser usage here:&lt;br /&gt;&lt;a href="http://www.w3schools.com/browsers/browsers_stats.asp"&gt;http://www.w3schools.com/browsers/browsers_stats.asp&lt;/a&gt;&lt;img hidden="true" style="border: medium none ; position: absolute; z-index: 2147483647; opacity: 0.6; display: none;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAADsElEQVR4nK2VTW9VVRSGn33OPgWpYLARbKWhQlCHTogoSkjEkQwclEQcNJEwlfgD/AM6NBo1xjhx5LyJ0cYEDHGkJqhtBGKUpm3SFii3vb2956wPB/t+9raEgSs52fuus89613rftdcNH8/c9q9++oe/Vzb5P+3McyNcfm2CcPj9af9w6gwjTwzvethx3Bx3x8xwd1wNM8dMcTNUHTfFLPnX6nVmZpeIYwf3cWD/PhbrvlPkblAzVFurKS6GmmGqqComaS+qmBoTI0Ncu3mXuGvWnrJ+ZSxweDgnkHf8ndVTdbiT3M7cQp2Z31dRTecHAfqydp4ejhwazh6Zezfnu98E1WIQwB3crEuJ2Y45PBTAQUVR9X4At66AppoEVO1Q8sgAOKJJjw6Am6OquDmvHskZ3R87gW+vlHz98zpmiqphkkRVbQtsfPTOC30lJKFbFTgp83bWh7Zx/uX1B6w3hI3NkkZTqEpBRDBRzG2AQHcwcYwEkOGkTERREbLQ/8HxJwuW7zdYrzfZ2iopy4qqEspKaDYravVm33k1R91Q69FA1VBRzFIVvXbx5AgXT44A8MWP81yfu0utIR2aVK3vfCnGrcUNxp8a7gKYKiLCvY2SUvo/aNtnM3e49ucK9S3p0aDdaT0UAVsKi2tVi6IWwNL9JvdqTdihaz79/l+u/rHMxmaJVMLkS2OoKKLWacdeE3IsSxctc2D5Qcl6vUlVVgNt+fkPPcFFmTw1xruvT7SCd7nuVhDQvECzJH90h0azRKoKFRkAmP5lKTWAGRdefoZL554FQNUxB92WvYeA5UN4PtSqwB2phKqsqMpBgAunRhFR3j49zuU3jnX8k6fHEQKXzh1jbmGDuYU6s4t1rt6socUeLLZHhYO2AHSHmzt19ihTZ48O8Hzl/AmunD/BjTvrvPfNX3hWsNpwJCvwYm+ngug4UilSCSq6k8YPtxDwfA+WRawIWFbgscDiULcCEaWqBFOlrLazurupOSHLqGnEKJAY8TwBEHumqUirAjNm52vEPPRV4p01XXMPAQhUBjcWm9QZwijwokgAeYHlHYA06KR1cT6ZvoV56pDUJQEjw0KeaMgj1hPEY4vz2A4eW0/e1qA7KtQdsxTYAG0H3iG4xyK1Y+xm7XmEPOJZDiENzLi2WZHngeOjj2Pe+sMg4GRYyLAsx7ME4FnsyTD9pr0PEc8zPGRAwKXBkYOPEd96cZRvf11g9MDe7e3R4Z4Q+vyEnn3P4t0XzK/W+ODN5/kPfRLewAJVEQ0AAAAASUVORK5CYII%3D" id="myFxSearchImg" height="24" width="24" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-276022495963145497?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/276022495963145497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/12/ie-6-display-problems.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/276022495963145497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/276022495963145497'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/12/ie-6-display-problems.html' title='IE 6 display problems'/><author><name>Dre</name><uri>http://www.blogger.com/profile/16368104993194304212</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-6588361131733153376</id><published>2009-12-10T14:10:00.000-08:00</published><updated>2009-12-10T14:10:19.626-08:00</updated><title type='text'>ALOHA FRIDAY !!</title><content type='html'>&lt;a href="http://www.thehanashirtco.com/blog/6"&gt;ALOHA FRIDAY !!&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-6588361131733153376?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.thehanashirtco.com/blog/6' title='ALOHA FRIDAY !!'/><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/6588361131733153376/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/12/aloha-friday.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6588361131733153376'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6588361131733153376'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/12/aloha-friday.html' title='ALOHA FRIDAY !!'/><author><name>sonia</name><uri>http://www.blogger.com/profile/04342699327155397193</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-6370696335732363308</id><published>2009-12-10T11:22:00.000-08:00</published><updated>2009-12-10T11:53:10.247-08:00</updated><title type='text'>Fireworks observations</title><content type='html'>Here are my findings so far and keep in mind this is with little to no Fireworks experience. These are basically notes I made for myself that are hopefully helpful to others.&lt;br /&gt;&lt;br /&gt;From what I found out so far is that Fireworks in not the solution to everything. It's a tool that's part of a greater tool. I would personally just use Fireworks to splice a layout in its basic structure export the css and images from there and work with either Dreamweaver or some other html editing tool.&lt;br /&gt;&lt;br /&gt;By basic I mean, background images, containers, logos, icons, and maybe even a few form items.&lt;br /&gt;&lt;br /&gt;This of course is coming from my experiences so far so my opinion and knowledge of Fireworks will most likely change in the future.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Copy and Pasting Text&lt;/span&gt;&lt;br /&gt;If you copy and paste text from PSD files over to a fireworks file. Be sure to name the actual element appropriately as if it were a html element otherwise it'll name the element as the text you just pasted.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Splicing&lt;/span&gt;&lt;br /&gt;When copying text from a PSD and pasting it into a FireWorks document make sure that the text container doesn't have an additional line break in it. I had an issue where I didn't realize there was an extra line break at the end of my text when I was thinking it had to do with the Leading aka line-height.&lt;br /&gt;&lt;br /&gt;Note: 120% Leading is normal&lt;br /&gt;&lt;br /&gt;When you're splicing images, I found that it defaults to an 80% quality,  so you may want to increase the quality level or make your own option when 80% doesn't cut it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Layers&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I find it really helpful for me to set up layers into sections of a page ie. footer, header, main content section. I found it helpful to also place any rectangle container sections within the appropriate layer.&lt;br /&gt;&lt;br /&gt;When selecting multiple layers by holding ctrl make sure you click on the name and not to the left of the layer otherwise it won't work.&lt;br /&gt;&lt;br /&gt;When implementing a PSD layout using Fireworks be sure to merge all layers appropriately to unsure the project is organized once it's imported into Fireworks.&lt;br /&gt;&lt;br /&gt;For instance if you have separate layers that make up one button you'll want to merge those layers into one and maybe just leave out the text for the button as a separate layer.&lt;br /&gt;&lt;br /&gt;Also don't merge header elements together unless they're absolutely necessary. For instance if you have a header bg image and you can't tile it make sure you don't merge&lt;br /&gt;logo's onto that header bg image. Separate it into one large background image.&lt;br /&gt;&lt;br /&gt;Right click the whole page to duplicate it... Set the top page to master by right clicking the page and selecting "Set as Master Page". From there you can modify the copied page to your liking and maintain layer structure. Simply hitting ctrl+c and ctrl+v would not work if you're trying to maintain layer structures.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Windows&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;When minimizing windows such as the layers window, single click it to minimize otherwise you may end up clicking other buttons, like the trash can button like I was doing. *sigh*&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Save As&lt;/span&gt;&lt;br /&gt;Make sure you save your work as a png, otherwise saving it as psd might cause some issues when reloading it in fireworks. &lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-6370696335732363308?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/6370696335732363308/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/12/fireworks-observations.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6370696335732363308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6370696335732363308'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/12/fireworks-observations.html' title='Fireworks observations'/><author><name>Doe</name><uri>http://www.blogger.com/profile/15822071924190395658</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-3958050375248649182</id><published>2009-12-06T15:08:00.000-08:00</published><updated>2009-12-06T15:08:15.438-08:00</updated><title type='text'>Fireworks Trick - Be Precise</title><content type='html'>Just a quick note to those of you out there using Fireworks CS4 and trying to get a quality XHTML / CSS / Images export that is easy to read and doesn't need a ton of tweaking afterwards.&lt;br /&gt;&lt;br /&gt;BE MATHEMATICALLY PRECISE&lt;br /&gt;&lt;br /&gt;When you're just quickly comping up wire-frames, it is fine to just rough up proportions, margins, padding, and spacing in general... but as you approach later revisions of the wire-frames, and they start to materialize as true page templates, start paying attention to the precise relative positioning of elements.&lt;br /&gt;&lt;br /&gt;Let your containers, backgrounds, images, headers, and other content be spaced with dimensions you would imagine wanting in a CSS file. I.E.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Keep all row elements having precisely the same Y coordinates for containers, don't let it be off by a pixel.&lt;/li&gt;&lt;li&gt;Same with columns, but of course, let them all have the same X coordinates.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Let all objects within containers be separated from each other by precisely proportional amounts (i.e. 10 px, 15px).&lt;/li&gt;&lt;li&gt;Keep duplicated object groupings using precisely the same proportions, but at their respective X &amp;amp; Y coordinates.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The primary benefit of being so precise before you export to CSS &amp;amp; Images is the readability of your final CSS and XHTML files. The numbers will make sense, especially if another developer is involved. Knowing Fireworks, probably all you'll have to do is group the elements similarly, and maybe reduce a few redundancies, but you won't have to worry about adjusting pixels.&lt;br /&gt;&lt;br /&gt;If you have to adjust pixels, make sure you do it in the fireworks file and re-export. Let the CSS developer override the Fireworks CSS in his own file rather than edit the export file. The goal is automation.&lt;br /&gt;&lt;br /&gt;A potential automation, if you can keep your Fireworks file this precise, is an automated refactoring of the CSS pixel based export into relative spacing and sizing by calculating the proportions in the document into percentage based spacing / sizing. You could whip up a quick PHP script to do this.&lt;br /&gt;&lt;br /&gt;Just some ideas on a Sunday afternoon working in Fireworks CS4.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-3958050375248649182?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/3958050375248649182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/12/fireworks-trick-be-precise.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/3958050375248649182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/3958050375248649182'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/12/fireworks-trick-be-precise.html' title='Fireworks Trick - Be Precise'/><author><name>ndrtek</name><uri>http://www.blogger.com/profile/01779131195591843080</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_ckDnExDhLgc/Ssuw7SZgd4I/AAAAAAAAAAM/e9ipBMcNrwc/S220/IT.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-6505934370020673983</id><published>2009-12-03T14:17:00.000-08:00</published><updated>2009-12-18T12:23:25.024-08:00</updated><title type='text'>Xml and php</title><content type='html'>&lt;span style="font-weight: bold;font-size:130%;" &gt;What is Xml?&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;XML stands for EXtensible Markup Language&lt;/li&gt;&lt;li&gt;XML is a markup language much like HTML&lt;/li&gt;&lt;li&gt;XML was designed to carry data, not to display data&lt;/li&gt;&lt;li&gt;XML tags are not predefined. You must define your own tags&lt;/li&gt;&lt;li&gt;XML is designed to be self-descriptive&lt;/li&gt;&lt;li&gt;XML is a W3C Recommendation&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;I have Xml, but I want to read it... What do I do?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The easiest thing to do is get SimpleXML on your server.  If your server support is &gt;= php 5 then it should be able to support it.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;$file = 'YourFile.xml'&lt;br /&gt;$xml = simplexml_load_file($file);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This will convert the well-formed XML document in the given file to an object.&lt;br /&gt;&lt;br /&gt;*WHERE TAG_NAME IS THE TAG (not a constant or property)*&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;XML will be accessible through $xml-&gt;TAG_NAME&lt;/li&gt;&lt;li&gt;XML arrays will be accessible through $xml-&gt;TAG_NAME[0]&lt;/li&gt;&lt;li&gt;XML arrays can be iterated through using simple foreach statements&lt;/li&gt;&lt;/ul&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;foreach ($xml-&gt;TAG_NAME as $tag) {&lt;br /&gt;    echo $tag;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Values must be cast into an appropriately to get a non SimpleXML object&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;(string) $xml-&gt;TAG_NAME;&lt;br /&gt;(int) $xml-&gt;TAG_NAME;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Easy Cheesy, 123 done!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-6505934370020673983?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/6505934370020673983/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/12/xml-and-php.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6505934370020673983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6505934370020673983'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/12/xml-and-php.html' title='Xml and php'/><author><name>Carey Hinoki</name><uri>http://www.blogger.com/profile/14192349328683858918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-5720062371192137613</id><published>2009-11-16T14:06:00.000-08:00</published><updated>2009-11-16T14:10:52.376-08:00</updated><title type='text'>Typography beyond fonts</title><content type='html'>&lt;span style="font-size:100%;"&gt;&lt;span style="font-family: verdana;"&gt;I do really appreciate smashing magazine and studies they do for the realm of web design… I reviewed this &lt;a href="http://spreadsheets.google.com/ccc?key=0AsK4MoYiBVMldE12V3FJYk95YVRUZ18xNDJNOVRrSHc&amp;amp;hl=de"&gt;great study&lt;/a&gt; today and decided that it is a good follow up to my blog entry about what fonts to use in web design.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;The fonts I was lamenting about previously are really just a small part of an overall larger field: Typography. Typography includes the font, font size, font color, background color, character and line spacing, etc.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;Good typography will allow the website’s audience to comprehend the website’s content quickly and easily. It is therefore an extremely important part of web design, regardless of the type of website (unless it’s purely graphical)… after all it doesn’t matter if you are reading a friend update on a social network, a blog entry, a product description on an e-commerce site or a news post…. you want to read / comprehend the information as quickly and effortless as possible.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: verdana;"&gt;So using &lt;a href="http://spreadsheets.google.com/ccc?key=0AsK4MoYiBVMldE12V3FJYk95YVRUZ18xNDJNOVRrSHc&amp;amp;hl=de"&gt;smashing magazines study&lt;/a&gt; and its &lt;a href="http://www.smashingmagazine.com/2009/08/20/typographic-design-survey-best-practices-from-the-best-blogs/"&gt;analysis&lt;/a&gt; as a base, I have come up with the following rules of thumb for good typography:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family: verdana;"&gt;Font Type: As discussed in the previous post. Here a quick refresher: When using a sans serif font for headline or body text use Verdana if possible, use Arial as a backup. Body text should usually be a sans serif font unless explicitly stated not to be. Please use Georgia as a Serif font. The contrast in between a sans serif font and a serif font makes Georgia a good choice for headlines if your body text is &lt;/span&gt;&lt;span style="font-family: verdana;"&gt;Verdana.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family: verdana;"&gt;&lt;/span&gt;&lt;span style="font-family: verdana;"&gt;Background Color: The general rule is that the bigger the contrast (difference) in between background and text, the better the readability. That is why all content heavy websites have one thing in common: white background with black text! Sounds boring? Maybe so… but unless you want to make a bold design statement and people visit your website for mostly aesthetic reasons, it is advisable to keep at least the background of the body content white with black or dark grey text so users can get the info they came to get as easily as possible.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family: verdana;"&gt;&lt;/span&gt;&lt;span style="font-family: verdana;"&gt;Headline Font Size: A font size of 18 to 20 points is ideal, but it can go up to 26. &lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family: verdana;"&gt;Body Copy Font Size: A font size of 12 to 14 points, with 13 being the most popular.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family: verdana;"&gt;Line Height: Best readability is achieved when the line height (and therefore the space in between new lines of text is increased) is 1.5&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family: verdana;"&gt;Line Length: you may have noted how cumbersome it is to read straight across a 1000px wide page. Line length should not to exceed 600px. The ideal line length is in between 500 and 600px.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-size:100%;"&gt;&lt;span style="font-family: verdana;"&gt;Maximum Characters: The ideal amount of characters per line is 73 to 90.&lt;/span&gt;&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;img hidden="true" style="border: medium none ; position: absolute; z-index: 2147483647; opacity: 0.6; display: none;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAADsElEQVR4nK2VTW9VVRSGn33OPgWpYLARbKWhQlCHTogoSkjEkQwclEQcNJEwlfgD/AM6NBo1xjhx5LyJ0cYEDHGkJqhtBGKUpm3SFii3vb2956wPB/t+9raEgSs52fuus89613rftdcNH8/c9q9++oe/Vzb5P+3McyNcfm2CcPj9af9w6gwjTwzvethx3Bx3x8xwd1wNM8dMcTNUHTfFLPnX6nVmZpeIYwf3cWD/PhbrvlPkblAzVFurKS6GmmGqqComaS+qmBoTI0Ncu3mXuGvWnrJ+ZSxweDgnkHf8ndVTdbiT3M7cQp2Z31dRTecHAfqydp4ejhwazh6Zezfnu98E1WIQwB3crEuJ2Y45PBTAQUVR9X4At66AppoEVO1Q8sgAOKJJjw6Am6OquDmvHskZ3R87gW+vlHz98zpmiqphkkRVbQtsfPTOC30lJKFbFTgp83bWh7Zx/uX1B6w3hI3NkkZTqEpBRDBRzG2AQHcwcYwEkOGkTERREbLQ/8HxJwuW7zdYrzfZ2iopy4qqEspKaDYravVm33k1R91Q69FA1VBRzFIVvXbx5AgXT44A8MWP81yfu0utIR2aVK3vfCnGrcUNxp8a7gKYKiLCvY2SUvo/aNtnM3e49ucK9S3p0aDdaT0UAVsKi2tVi6IWwNL9JvdqTdihaz79/l+u/rHMxmaJVMLkS2OoKKLWacdeE3IsSxctc2D5Qcl6vUlVVgNt+fkPPcFFmTw1xruvT7SCd7nuVhDQvECzJH90h0azRKoKFRkAmP5lKTWAGRdefoZL554FQNUxB92WvYeA5UN4PtSqwB2phKqsqMpBgAunRhFR3j49zuU3jnX8k6fHEQKXzh1jbmGDuYU6s4t1rt6socUeLLZHhYO2AHSHmzt19ihTZ48O8Hzl/AmunD/BjTvrvPfNX3hWsNpwJCvwYm+ngug4UilSCSq6k8YPtxDwfA+WRawIWFbgscDiULcCEaWqBFOlrLazurupOSHLqGnEKJAY8TwBEHumqUirAjNm52vEPPRV4p01XXMPAQhUBjcWm9QZwijwokgAeYHlHYA06KR1cT6ZvoV56pDUJQEjw0KeaMgj1hPEY4vz2A4eW0/e1qA7KtQdsxTYAG0H3iG4xyK1Y+xm7XmEPOJZDiENzLi2WZHngeOjj2Pe+sMg4GRYyLAsx7ME4FnsyTD9pr0PEc8zPGRAwKXBkYOPEd96cZRvf11g9MDe7e3R4Z4Q+vyEnn3P4t0XzK/W+ODN5/kPfRLewAJVEQ0AAAAASUVORK5CYII%3D" id="myFxSearchImg" height="24" width="24" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-5720062371192137613?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/5720062371192137613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/11/typography-beyond-fonts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5720062371192137613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5720062371192137613'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/11/typography-beyond-fonts.html' title='Typography beyond fonts'/><author><name>Dre</name><uri>http://www.blogger.com/profile/16368104993194304212</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-5449135740833380919</id><published>2009-11-14T00:52:00.000-08:00</published><updated>2009-11-14T02:10:36.423-08:00</updated><title type='text'>Joomla experience with breadcrumbs, menualias, and SEF</title><content type='html'>So today in my Joomla experience I began to seek out a problem dealing with SEF and Routing.  I had specific goals in mind and wanted to execute them... so what were they?&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;SEF urls (search engine friendly)&lt;/li&gt;&lt;li&gt;custom urls&lt;/li&gt;&lt;li&gt;custom breadcrumbs&lt;/li&gt;&lt;li&gt;modified active menu to accommodate for the custom changes&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;So where to start?? My first stop.. JRouter and http://docs.joomla.org/Routing&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Component Routing]&lt;/span&gt;&lt;br /&gt;Component routing is handled in the router.php under a specific component.&lt;br /&gt;&lt;br /&gt;components/{yourcomponent}/router.php&lt;br /&gt;&lt;br /&gt;There are two functions that make up the router.php file.  These are a build function and a parse function.  What does this mean for you?  In a sense, you get to customize what is already in the component url and add your own flare.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Component Routing - What I wanted to do]&lt;/span&gt;&lt;br /&gt;http://www.oghead.com/component/flash/flash/80.&lt;br /&gt;&lt;br /&gt;This url is what I started with after turning on the SEF feature in the administration.  Ignoring the first part "component/flash", the routing.php file accepts the parameters "flash" and "80".&lt;br /&gt;&lt;br /&gt;The "flash" is the component view your looking at and "80" is the id of the item being displayed. I wanted to be able to have the item name displayed in the url.  To accomplish there are two functions listed under http://docs.joomla.org/Routing&lt;br /&gt;&lt;ul&gt;&lt;li&gt;function [componentname]BuildRoute( &amp;amp;$query )&lt;/li&gt;&lt;li&gt;function [componentname]ParseRoute( $segments )&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;My new url became http://www.oghead.com/component/flash/flash/80-mygamename.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;*Done*&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Custom Urls]&lt;/span&gt;&lt;br /&gt;Custom urls are a funny thing.  I never did figure out what the "proper" way of doing them is.  I spent a good 8-16 hours searching forums and threads and articles for a solution, but alas no help.  I even went to the lengths of creating my first community account EVER and posted a thread on forum.joomla.org!  As detailed a post as it was... no response!&lt;br /&gt;&lt;br /&gt;The idea of custom urls is whatever your imagination leads you.  If you want http://www.yoursite.com/michaeljackson to go to the Articles component more freedom to you! BUT HOW!&lt;br /&gt;&lt;br /&gt;If you want http://www.yoursite.com/jane/josh/joe/jill/amy to go to the contacts page, congratulations! BUT HOW!~&lt;br /&gt;&lt;br /&gt;Taking a step back.  Urls are driven by the JRouting class that Joomla provides.  Urls get changed based on the system's global configuration.  If you have SEO Settings &gt; Search Engine Friendly URLs turned on, then Joomla displays all links and urls differently.&lt;br /&gt;&lt;br /&gt;The SEF makes urls go from...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://www.yoursite.com/index.php?option=com_hello&amp;amp;view=hello_world&amp;amp;id=5&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;To...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://www.yoursite.com/component/hello/hello_world/5&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;The second url is definitely a much prettier url.  Urls are also driven by menus.  This makes things problematic.  If you click into a menu item, your urls become dependant on the menu item that is currently active.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Custom Urls - What I wanted to do]&lt;/span&gt;&lt;br /&gt;Turn...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://www.oghead.com/component/flash/flash/80-mygamename&lt;/li&gt;&lt;li&gt;http://www.oghead.com/action/flash/80-mygamename&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Into...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://www.oghead.com/play/flash/80-mygamename&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;As you can see this is problematic.  You do not want multiple urls pointing to the same end.  This means that to get to item 80, there can be an N amount of URLs pointing to the same place!  This means google is going to index N amount of urls to that location and a N amount of instances where that itself happens.&lt;br /&gt;&lt;br /&gt;I tried looking for a Routing solution but I came up empty handed.  Therefore that left me with a .htaccess solution.&lt;br /&gt;&lt;br /&gt;In the .htaccess file located at the root web dir I added&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;#Force play flash into 1 URL&lt;br /&gt;RewriteEngine On&lt;br /&gt;&lt;br /&gt;RewriteRule ^play/flash/([\d]+)-(.+) index.php?option=com_flash&amp;amp;view=flash&amp;amp;id=$1&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This grabs any url that has play/flash/{a number of some size}-{any characters following said hyphen}, it translate the url given into what Joomla can read.&lt;br /&gt;&lt;br /&gt;Now...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://www.oghead.com/play/flash/80-mygamename&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Successfully points to...&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://www.oghead.com/index.php?option=com_flash&amp;amp;view=flash&amp;amp;id=80 (where $1 is the first parathesis match) &lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I had to change all my links to accommodate for the new url by calling "play/flash/id" instead, but now I have one pretty url per page.&lt;br /&gt;&lt;span style="font-style: italic;"&gt;*Done*&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Custom breadcrumbs]&lt;/span&gt;&lt;br /&gt;Breadcrumbs are created based on menu items.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Custom breadcrumbs - What I wanted to do]&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://www.oghead.com/component/flash/flash/80-mygamename (Breadcrumb: Home)&lt;/li&gt;&lt;li&gt;http://www.oghead.com/action/flash/80-mygamename (Breadcrumb: Home &gt; Action)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;==After the modifications above my url is now==&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://www.oghead.com/play/flash/80-mygamename (Breadcrumb: Home)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;I wanted each link to have the breadcrumb of Home &gt; Category &gt; Mygamename&lt;br /&gt;&lt;br /&gt;To fix this I made some modifications to my component view file.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;$pathway =&amp;amp; $mainframe-&gt;getPathway();&lt;br /&gt;$pathway-&gt;addItem({menu name}, 'index.php?Itemid={menu id});&lt;br /&gt;$pathway-&gt;addItem({mygamename});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This adds two breadcrumbs onto the existing "Home" breadcrumb.  The first parameter is the name, the second is the link the breadcrumb goes to.&lt;br /&gt;&lt;br /&gt;Now my breadcrumb for this item is Home &gt; Action &gt; Mygamename&lt;br /&gt;&lt;span style="font-style: italic;"&gt;*Done*&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[Active Menu Issue]&lt;/span&gt;&lt;br /&gt;I set up my menu as different category views inside my component.  These categories were Home, Action, Strategy, Etc.&lt;br /&gt;&lt;br /&gt;An active class gets put on menu items in which are active.  If you are at the "Home" page, then the cooresponding menu item "Home" gets the class of "active".  Now you can style your template based on the menu item that is active.&lt;br /&gt;&lt;br /&gt;However, this poses some problems with items we have already addressed.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;http://www.oghead.com (Home is active)&lt;/li&gt;&lt;li&gt;http://www.oghead.com/component/flash/flash/80 (Nothing is active - If no menu item is active then it means you navigated to item 80 from the Homepage the default menu item becomes component/flash)&lt;/li&gt;&lt;li&gt;http://www.oghead.com/action (Action is active)&lt;/li&gt;&lt;li&gt;http://www.oghead.com/action/flash/80 (Action is active)&lt;/li&gt;&lt;li&gt;http://www.oghead.com/play/flash/80 (Nothing is active)&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Notice the first two links.  They should both have Home active just like Action is active both times.  Since we changed the url to be play/flash however, we need to accommodate for this  change and make the correct menu item active.&lt;br /&gt;&lt;br /&gt;This is done by figuring out which menu item you should be at and overwriting the active menu item.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;$menu = &amp;amp;JSite::getMenu();&lt;br /&gt;$menu-&gt;setActive($flash-&gt;item_id);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now since play/flash/80-mygamename is an Action game.  We need to get the item_id that corresponds to Action and use the code block above to set it as the active menu item!&lt;br /&gt;&lt;span style="font-style: italic;"&gt;*Done*&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-5449135740833380919?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/5449135740833380919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/11/joomla-experience-with-breadcrumbs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5449135740833380919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5449135740833380919'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/11/joomla-experience-with-breadcrumbs.html' title='Joomla experience with breadcrumbs, menualias, and SEF'/><author><name>Carey Hinoki</name><uri>http://www.blogger.com/profile/14192349328683858918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-5357245520089835381</id><published>2009-11-09T13:28:00.000-08:00</published><updated>2009-11-18T09:21:07.790-08:00</updated><title type='text'>Testing, Testing…</title><content type='html'>&lt;!--  /* Style Definitions */  p.MsoNormal, li.MsoNormal, div.MsoNormal  {mso-style-parent:"";  margin:0in;  margin-bottom:.0001pt;  mso-pagination:widow-orphan;  font-size:12.0pt;  font-family:"Times New Roman";  mso-fareast-font-family:"Times New Roman";} @page Section1  {size:8.5in 11.0in;  margin:1.0in 1.25in 1.0in 1.25in;  mso-header-margin:.5in;  mso-footer-margin:.5in;  mso-paper-source:0;} div.Section1  {page:Section1;} --&gt;   I recently came across some interesting studies in regards to project testing. We already have a pretty powerful method with our alpha and beta testing procedures, as well as with our online issue / bug tracking system, but what I’ve read may help us to be even more efficient during this important part of a given project.&lt;br /&gt;&lt;br /&gt;The most informative study that I read was one done by Jacob Nielsen, the so called guru of Web Page Usability, and his company Nielsen Norman Group. Although the study is older, I still believe its core findings are true… because if anything, websites / web apps have gotten more complex since 2000 and therefore offer more room for bugs.&lt;br /&gt;&lt;br /&gt;The study finds that rather than one specific method of testing, the trick to effective testing is the use of multiple testing individuals (besides the original engineer). The benefits of multiple user testing as revealed in the study are astonishing: Just adding one other person (that is not deeply involved in the project) to test it out, finds a third of all bugs. Adding a second person brings that number up to 50% of all bugs found. At a level of 5 individual testers, the optimum ratio of testers to bugs found is achieved (about 85%). Any larger group of testers will not contribute significant enough amounts of bugs found to justify the added cost.&lt;br /&gt;&lt;br /&gt;Conclusion: Always have your coworkers check out your work before showing it to the client, so you can gather their (most likely very helpful) feedback. Ideally have at least two other people that where not deeply involved in the project examine it and walk through the site / app as a general user of it would do.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-5357245520089835381?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/5357245520089835381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/11/testing-testing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5357245520089835381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5357245520089835381'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/11/testing-testing.html' title='Testing, Testing…'/><author><name>Dre</name><uri>http://www.blogger.com/profile/16368104993194304212</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-1485706296706157263</id><published>2009-11-08T22:33:00.000-08:00</published><updated>2009-11-08T22:52:12.971-08:00</updated><title type='text'>Sending email with attachment in php</title><content type='html'>Programmers using PHP language can the mail() function to send emails.&lt;br /&gt;&lt;br /&gt;The purpose of this blog entry is to demonstrate how to send emails with attachment using the mail() function.&lt;br /&gt;&lt;br /&gt;mail() function definition is the following:&lt;br /&gt;&lt;br /&gt;&lt;span class="type"&gt;bool&lt;/span&gt; &lt;span class="methodname"&gt;&lt;b&gt;mail&lt;/b&gt;&lt;/span&gt;     ( &lt;span class="methodparam"&gt;&lt;span class="type"&gt;string&lt;/span&gt; &lt;tt class="parameter"&gt;$to&lt;/tt&gt;&lt;/span&gt;    , &lt;span class="methodparam"&gt;&lt;span class="type"&gt;string&lt;/span&gt; &lt;tt class="parameter"&gt;$subject&lt;/tt&gt;&lt;/span&gt;    , &lt;span class="methodparam"&gt;&lt;span class="type"&gt;string&lt;/span&gt; &lt;tt class="parameter"&gt;$message&lt;/tt&gt;&lt;/span&gt;    [, &lt;span class="methodparam"&gt;&lt;span class="type"&gt;string&lt;/span&gt; &lt;tt class="parameter"&gt;$additional_headers&lt;/tt&gt;&lt;/span&gt;    [, &lt;span class="methodparam"&gt;&lt;span class="type"&gt;string&lt;/span&gt; &lt;tt class="parameter"&gt;$additional_parameters&lt;/tt&gt;&lt;/span&gt;   ]] )&lt;br /&gt;&lt;br /&gt;To send an email with attachment we need to use the multipart/mixed MIME type that specifies that mixed types will be included in the email. Moreover, we want to use multipart/alternative MIME type to send both plain-text and HTML version of the email. Have a look at the example:&lt;br /&gt;&lt;br /&gt;&lt;?php&lt;br /&gt;&lt;span class="comment"&gt;//define the receiver of the email&lt;/span&gt;&lt;br /&gt;$to = 'receiveraddress@example.com';&lt;br /&gt;&lt;span class="comment"&gt;//define the subject of the email&lt;/span&gt;&lt;br /&gt;$subject = 'Test email with attachment';&lt;br /&gt;&lt;span class="comment"&gt;//create a boundary string. It must be unique&lt;br /&gt;//so we use the MD5 algorithm to generate a random hash&lt;/span&gt;&lt;br /&gt;$random_hash = md5(date('r', time()));&lt;br /&gt;&lt;span class="comment"&gt;//define the headers we want passed. Note that they are separated with \r\n&lt;/span&gt;&lt;br /&gt;$headers = "From: webmaster@example.com\r\nReply-To: webmaster@example.com\r\n";&lt;br /&gt;&lt;span class="comment"&gt;//add boundary string and mime type specification&lt;/span&gt;&lt;br /&gt;$headers .= "Content-Type: multipart/mixed; boundary=\"PHP-mixed-".$random_hash."\" \r\n";&lt;br /&gt;&lt;span class="comment"&gt;//read the atachment file contents into a string,&lt;br /&gt;//encode it with MIME base64,&lt;br /&gt;//and split it into smaller chunks&lt;/span&gt;&lt;br /&gt;$attachment = chunk_split(base64_encode(file_get_contents('attachment.zip')));&lt;br /&gt;&lt;span class="comment"&gt;//define the body of the message.&lt;/span&gt;&lt;br /&gt;ob_start(); &lt;span class="comment"&gt;//Turn on output buffering&lt;/span&gt;&lt;br /&gt;?&gt;&lt;br /&gt;--PHP-mixed-&lt;?php echo $random_hash; ?&gt; &lt;br /&gt;Content-Type: multipart/alternative; boundary="PHP-alt-&lt;?php echo $random_hash; ?&gt;"&lt;br /&gt;&lt;br /&gt;--PHP-alt-&lt;?php echo $random_hash; ?&gt; &lt;br /&gt;Content-Type: text/plain; charset="iso-8859-1"&lt;br /&gt;Content-Transfer-Encoding: 7bit&lt;br /&gt;&lt;br /&gt;Hello World!!!&lt;br /&gt;This is a sample text email.&lt;br /&gt;&lt;br /&gt;--PHP-alt-&lt;?php echo $random_hash; ?&gt; &lt;br /&gt;Content-Type: text/html; charset="iso-8859-1"&lt;br /&gt;Content-Transfer-Encoding: 7bit&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Hello World!&lt;/h2&gt;&lt;br /&gt;&lt;p&gt;This is an &lt;b&gt;HTML&lt;/b&gt; email.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;--PHP-alt-&lt;?php echo $random_hash; ?&gt;--&lt;br /&gt;&lt;br /&gt;--PHP-mixed-&lt;?php echo $random_hash; ?&gt; &lt;br /&gt;Content-Type: application/zip; name="attachment.zip" &lt;br /&gt;Content-Transfer-Encoding: base64 &lt;br /&gt;Content-Disposition: attachment &lt;br /&gt;&lt;br /&gt;&lt;?php echo $attachment; ?&gt;&lt;br /&gt;--PHP-mixed-&lt;?php echo $random_hash; ?&gt;--&lt;br /&gt;&lt;br /&gt;&lt;?php&lt;br /&gt;&lt;span class="comment"&gt;//copy current buffer contents into $message variable and delete current output buffer&lt;/span&gt;&lt;br /&gt;$message = ob_get_clean();&lt;br /&gt;&lt;span class="comment"&gt;//send the email&lt;/span&gt;&lt;br /&gt;$mail_sent = @mail( $to, $subject, $message, $headers );&lt;br /&gt;&lt;span class="comment"&gt;//if the message is sent successfully print "Mail sent". Otherwise print "Mail failed" &lt;/span&gt;&lt;br /&gt;echo $mail_sent ? "Mail sent" : "Mail failed";&lt;br /&gt;?&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the example above, to include an attachment to our message, we read the data from the specified file into a string, encode it with base64,  split it in smaller chunks to make sure that it matches the MIME specifications and then include it as an attachment.&lt;br /&gt;&lt;br /&gt;On the side note: make sure you don't have any white spaces like tabs or spaces before Content-type.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-1485706296706157263?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/1485706296706157263/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/11/sending-email-with-attachment-in-php.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/1485706296706157263'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/1485706296706157263'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/11/sending-email-with-attachment-in-php.html' title='Sending email with attachment in php'/><author><name>Minh Nguyen</name><uri>http://www.blogger.com/profile/16405413186830228269</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='30' height='32' src='http://1.bp.blogspot.com/_MyT6B1d1NNU/SsY56fwb9ZI/AAAAAAAAAAM/Pwz8UW-rwm0/S220/profile.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-7634185129904905735</id><published>2009-11-03T14:33:00.001-08:00</published><updated>2009-11-03T15:41:19.906-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='symfony'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud sites symlink'/><category scheme='http://www.blogger.com/atom/ns#' term='rackspace cloud sites'/><category scheme='http://www.blogger.com/atom/ns#' term='php shell'/><category scheme='http://www.blogger.com/atom/ns#' term='sshfs'/><category scheme='http://www.blogger.com/atom/ns#' term='rsync'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud session'/><category scheme='http://www.blogger.com/atom/ns#' term='symfony cloud'/><title type='text'>Rackspace Cloud Sites Gotchas</title><content type='html'>&lt;a href="http://www.rackspacecloud.com/cloud_hosting_products/sites"&gt;Rackspace Cloud Sites&lt;/a&gt; Gotchas.&lt;br /&gt;&lt;br /&gt;I'll share a few gotchas we came across on a recent deployment that are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Symlinks aren't supported! Sure, your symlink may work today, but Rackspace isn't concerned or responsible if it magically breaks tomorrow.&lt;/li&gt;&lt;li&gt;Default session storage /var/lib/php/sessions is not cloud persistent. Cloud node goes down or too busy to handle the request? Session lost. Be sure to store sessions in web/sessions for security and persistence.&lt;/li&gt;&lt;li&gt;No standard error messages. Cloud down? (Yes, the cloud has gone down.) You'll get a nice "No suitable nodes are available" error page. No error branding here.&lt;/li&gt;&lt;li&gt;Do you like a shell, rsync, or scp? We do too. Too bad Rackspace doesn't. Use &lt;a href="http://fuse.sourceforge.net/sshfs.html"&gt;SSHFS&lt;/a&gt; + Rsync to at least minimize the frustration. Use &lt;a href="http://phpshell.sourceforge.net/"&gt;PHP Shell&lt;/a&gt; for a shell.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Using sshfs and want to move your secure passwords to a secure publickey? Shucks. You can't.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Developed your app with the amazing &lt;a href="http://www.symfony-project.org/"&gt;Symfony framework&lt;/a&gt;? Good. Just you can't symlink and you can't change DocumentRoot or add an Alias. So rename that web/ to content/! I hope you used sfConfig::get('sf_web_dir') in the code ;)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-7634185129904905735?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/7634185129904905735/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/11/rackspace-cloud-sites-gotchas.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/7634185129904905735'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/7634185129904905735'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/11/rackspace-cloud-sites-gotchas.html' title='Rackspace Cloud Sites Gotchas'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-6806976622620078322</id><published>2009-11-02T12:47:00.000-08:00</published><updated>2009-11-02T12:48:38.971-08:00</updated><title type='text'>A whole lot of space… white space that is…</title><content type='html'>Smashing Magazine explains white space well:&lt;br /&gt;&lt;br /&gt;Most designers know the value of white space, which is the empty space between paragraphs, pictures, buttons and other items on the page. White space de-clutters a page by giving items room to breathe. We can also group items together by decreasing the space between them and increasing the space between them and other items on the page. This is important for showing relationships between items (e.g. showing that this button applies to this set of items) and building a hierarchy of elements on the page.&lt;br /&gt;White space also makes content more readable. A study (Lin, 2004) found that good use of white space between paragraphs and in the left and right margins increases comprehension by almost 20%. Readers find it easier to focus on and process generously spaced content.&lt;br /&gt;In fact, according to Chaperro, Shaikh and Baker, the layout on a Web page (including white space, headers, indentation and figures) may not measurably influence performance but does influence user satisfaction and experience.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So why do you as an engineer / project manager need to consider this?&lt;br /&gt; &lt;br /&gt;Giving your layout / design adequate white space starts with the wire frames / prototypes that we create for most of our projects. Since prototyping is essentially the first step of page design (because you determine a rough layout, elements on the page, etc), giving your items on a page adequate white space will help you and your client to determine the right amount of content and layout of a page. It will help your architectural decisions, because you can determine from your prototype how good the page flows, how well information is perceived, what elements are more prioritized than others, etc. So please allow for enough room when prototyping and make sure that clients with a lot of content to cram onto one page, understand why it is important to let the content breath.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-6806976622620078322?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/6806976622620078322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/11/whole-lot-of-space-white-space-that-is.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6806976622620078322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6806976622620078322'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/11/whole-lot-of-space-white-space-that-is.html' title='A whole lot of space… white space that is…'/><author><name>Dre</name><uri>http://www.blogger.com/profile/16368104993194304212</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-6705539977674414664</id><published>2009-10-30T06:10:00.000-07:00</published><updated>2009-10-30T06:46:12.001-07:00</updated><title type='text'>Webserver Batch Printing to Networked Printers</title><content type='html'>&lt;span style="font-size:85%;"&gt;&lt;span style="font-style: italic;"&gt;This will be the first of a series of posts that covers a solution that allows printing of multiple documents stored on a webserver to individual user printers. &lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Need&lt;/span&gt;&lt;br /&gt;Recently a client requested a way for their office personnel to be able to print multiple documents at once. The documents were stored on a webserver, and the way they had been doing it was to download each individual document, open it up, and then issue the print command from the application. A slow and tedious method for sure, especially when they had to print more than a few documents at a time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The Solution&lt;/span&gt;&lt;br /&gt;After some thinking, I determined the best way for this to happen was to have the webserver itself send the print jobs directly to the user's printers. This would remove the need for the user to download and open anything, and the server could send multiple documents to the printer at once. The only requirement was that each of the user's printers had to have a network interface. I considered first just having a printer directly connected to the webserver, but for this situation it was not practical because:&lt;br /&gt;1) the webserver was not accessible to the users.&lt;br /&gt;2) a single printer receiving multiple batch print jobs would get bogged down, and users would have to wait.&lt;br /&gt;3) the users would be inconvenienced by having to retrieve their print outs from another location other than the printers at their desks.&lt;br /&gt;&lt;br /&gt;Now that I had an idea of the solution, I needed the technology to make it happen. I found that CUPS (Common Unix Printing System) had the capability to turn the webserver into a network printserver, and in turn direct output to specific network printers. I installed CUPS, and then through its painless management interface (accessed through a browser on port 631), I set up each of the network printers by specifying a name and IP address for each. Now that the printers were setup, I could simply print to them by sending 'lpr -P &amp;lt;printer_name&amp;gt;' from the command line. CUPS also takes a variety of command line arguments that can help fine tune the printout, if needed (to be covered in a later post).&lt;br /&gt;&lt;br /&gt;For the batch print interface, I added a 'Print' button to the documents list page. The page has a filter so the users can specify which document set they wish to print. When they hit the print button, any documents returned by the filter are sent via CUPS to their personal printer. The print button itself is a submit button that executes a routine on postback that takes the current filter query, selects the documents, and then loops through the result set issuing the 'lpr -P &amp;lt;printer_name&amp;gt; &amp;lt;file_location&amp;gt;' command for each.&lt;br /&gt;&lt;br /&gt;The only trick left was how to determine which printer should receive a job based on the user. I accomplished this by adding a field to the user table that stores the CUPS printer name for the assigned printer. Since user info is stored in the session after they login, the printer name is easily accessible at any time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;That covers the overview of the solution. In future posts I'll go over the more technical details of the solution. I'll be covering CUPS printer setup and management, installation of printer drivers, and queue management.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-6705539977674414664?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/6705539977674414664/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/webserver-batch-printing-to-networked.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6705539977674414664'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6705539977674414664'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/webserver-batch-printing-to-networked.html' title='Webserver Batch Printing to Networked Printers'/><author><name>Brian Miller</name><uri>http://www.blogger.com/profile/11567586415437722452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-2657180876345699579</id><published>2009-10-26T15:24:00.000-07:00</published><updated>2009-10-26T15:26:40.238-07:00</updated><title type='text'>Above the fold</title><content type='html'>Ok, so we are all on board with the ideal page width because of my recent blog entry, right (that would be nice). So let’s get into the height of a page, positioning of main content and the users willingness to scroll…&lt;br /&gt;&lt;br /&gt;We’ll start with the ideal page height, or where you can assume a page break will show for the majority of users. That magic number is 768 pixels. So if a client is set on having a no scroll page, no content should go below 768px from the top. A clients insistence on no scroll often times leads to cramping of the content, loss of adequate white space and therefore to poor readability of the content. &lt;br /&gt;&lt;br /&gt;Rather than completely restricting page height, we should try to guide these types of clients towards prioritizing content. The basic rule for what should always be above the fold is this: Name / logo CI stuff; Navigation for the main sections; Value proposition of the website (i.e. what benefit users will get from using it).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;These thoughts above where spurred by some articles / research I recently read that are concerned with a user's willingness to scroll. Here are links to a couple if you want deeper info:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.boxesandarrows.com/view/blasting-the-myth-of"&gt;http://www.boxesandarrows.com/view/blasting-the-myth-of&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.clicktale.com/?p=19"&gt;http://blog.clicktale.com/?p=19&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The conclusion for the research I read was this: 78% of the users were actually scrolling down a page automatically, (as long as the content was exactly what they where looking for) because they are so into reading what is new or what this website can do for them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-2657180876345699579?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/2657180876345699579/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/above-fold.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/2657180876345699579'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/2657180876345699579'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/above-fold.html' title='Above the fold'/><author><name>Dre</name><uri>http://www.blogger.com/profile/16368104993194304212</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-4039722151108127601</id><published>2009-10-23T13:02:00.001-07:00</published><updated>2009-10-28T12:36:44.361-07:00</updated><title type='text'>SQL to grab latest records based on date field</title><content type='html'>This example will show you how to grab the latest records from a table (based on an effective-date field) using only one query.&lt;br /&gt;&lt;br /&gt;For this example, let's say we have the following products table:&lt;br /&gt;&lt;pre&gt;item      effectiveAt    price&lt;br /&gt;----      -----------    -----&lt;br /&gt;shoes     2009-10-07     1.29&lt;br /&gt;shoes     2009-08-03     1.59&lt;br /&gt;shoes     2009-04-06     2.29&lt;br /&gt;shirt     2009-07-13     1.47&lt;br /&gt;shirt     2009-08-28     1.59&lt;br /&gt;tie       2009-04-28     2.57&lt;br /&gt;tie       2009-07-09     3.19&lt;br /&gt;tie       2009-09-05     3.57&lt;br /&gt;&lt;/pre&gt;The most common way people address this is to use a subquery such as:&lt;pre name="code" class="sql"&gt;SELECT *&lt;br /&gt;FROM products AS p1&lt;br /&gt;WHERE effectiveAt = (&lt;br /&gt; SELECT MAX(effectiveAt)&lt;br /&gt; FROM products AS p2&lt;br /&gt; WHERE p1.item = p2.item&lt;br /&gt;)&lt;br /&gt;&lt;/pre&gt;The problem with this query is that for every unique item, a subquery is run. That can be a lot of queries and it's generally a good idea to avoid subqueries if at all possible.&lt;br /&gt;&lt;br /&gt;Here is how to get the same results with only one query:&lt;br /&gt;&lt;pre name="code" class="sql"&gt;SELECT * FROM products AS p1&lt;br /&gt;LEFT JOIN products AS p2 ON (&lt;br /&gt;p1.item = p2.item AND&lt;br /&gt;p1.effectiveAt &amp;lt; p2.effectiveAt) &lt;br /&gt;WHERE p2.effectiveAt IS NULL&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This query selects each item and left joins another record with a greater effective date. The one actually returned is where p2.effectiveAt IS NULL, which means p1.effectiveAt is the greatest effectiveAt for that product. To get a better idea of how it actually works, just run the query without the 'WHERE p2.effectiveAt IS NULL'.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-4039722151108127601?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/4039722151108127601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/sql-to-grab-latest-records-based-on.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/4039722151108127601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/4039722151108127601'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/sql-to-grab-latest-records-based-on.html' title='SQL to grab latest records based on date field'/><author><name>Brian Miller</name><uri>http://www.blogger.com/profile/11567586415437722452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-5402592329958648493</id><published>2009-10-23T11:53:00.001-07:00</published><updated>2009-10-28T11:02:02.117-07:00</updated><title type='text'>Joomla Partials</title><content type='html'>HOW THE HECK DO YOU DO PARTIALS IN JOOMLA!&lt;br /&gt;&lt;br /&gt;This is one of the most frustrating issues I have seen in Joomla.  There is no method of reusing code in Joomla.&lt;br /&gt;&lt;br /&gt;Joomla is broken down into 3 major parts.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Components&lt;/li&gt;&lt;li&gt;Modules&lt;/li&gt;&lt;li&gt;Views of Components or Modules&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;Joomla does allow the reuse of modules.  However, how often do you want to include multiple modules on the same site?  Cool ....&lt;br /&gt;&lt;br /&gt;If you include a twitter module feed.  It is possible that you might want to include different twitter feeds, but more likely than not you will just have one site feed.&lt;br /&gt;&lt;br /&gt;However.. It is MORE likely that you will want to reuse the &lt;span style="font-weight: bold;"&gt;Views of Components or Modules&lt;/span&gt;.  It is possible that you want to create one form and use it multiple places.  It is possible that you have repeated code in different view directories.&lt;br /&gt;&lt;br /&gt;If this is the case you do &lt;span style="font-weight: bold;"&gt;NOT &lt;/span&gt;want to have the same code repeated whatsoever, complex or not.  Joomla does not provide a method for this.  Instead they offer the newbie solution of...&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;$html = '';&lt;br /&gt;$html .= '&amp;lt;div&amp;gt;';&lt;br /&gt;$html .= 'Your Content';&lt;br /&gt;$html .= '&amp;lt;/div&amp;gt;';&lt;br /&gt;&lt;br /&gt;echo $html;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;BUT I have a solution... Thanks Robbie!&lt;br /&gt;&lt;br /&gt;For now, I included this in my custom components helper file, but once I have access to custom created site-wide functions (e.g. JSite, JRequest).  I will refactor it so that I can pass in components and call the function from anywhere to anywhere.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;  /**&lt;br /&gt;   * Helper Functions&lt;br /&gt;   *&lt;br /&gt;   */&lt;br /&gt;  function include_partial($name, $params = array()) {&lt;br /&gt;      $partial_file = JPATH_COMPONENT.DS.'helpers'.DS.'_'.$name.'.php';&lt;br /&gt;   &lt;br /&gt;      if (!is_file($partial_file)) {&lt;br /&gt;          JError::raiseError(500, JText::_($partial_file.' not found!') );&lt;br /&gt;      }&lt;br /&gt;   &lt;br /&gt;      ob_start();&lt;br /&gt;   &lt;br /&gt;      extract($params);&lt;br /&gt;      require($partial_file);&lt;br /&gt;   &lt;br /&gt;      $partial = ob_get_clean();&lt;br /&gt;      echo $partial;&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This function allows you to pass in the name of the partial file and an array of parameters.  These parameters will be available to the partial file.  You can then write actual html/php without being retarded.  No more concatinating html into strings.&lt;br /&gt;&lt;br /&gt;This is a replicated symfony slot, but easy enough to use as a get_partial.&lt;br /&gt;&lt;br /&gt;Xie Xie.  Arigato.  Gracias.  Thank you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-5402592329958648493?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/5402592329958648493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/joomla-partials.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5402592329958648493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5402592329958648493'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/joomla-partials.html' title='Joomla Partials'/><author><name>Carey Hinoki</name><uri>http://www.blogger.com/profile/14192349328683858918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-8864846771438846600</id><published>2009-10-23T11:34:00.000-07:00</published><updated>2009-10-23T12:05:33.355-07:00</updated><title type='text'>Joomla Exceptions</title><content type='html'>Joomla Exceptions!  Another piece of the puzzle.&lt;br /&gt;&lt;br /&gt;Starting Joomla can be frustrating.. Especially when you may be use to another framework or style of coding...  Thoughts run through your mind, "What is Joomla's equivalent method!".&lt;br /&gt;&lt;br /&gt;If you are trying to prevent people from accessing pages that you create.   One of the ways to do that is by throwing an exception.  Most of the time you want to prevent people from entering in bad urls.&lt;br /&gt;&lt;br /&gt;Yoursite.com/index.php?my_content_id=apple&lt;br /&gt;&lt;br /&gt;Most likely you do not want to accept apple as an id parameter.  This can be solved by throwing an exception if valid content is not retrieved from "my_content_id=apple"&lt;br /&gt;&lt;br /&gt;So how do you handle Exceptions?&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Using or customizing the exception page under templates/system/error.php&lt;/li&gt;&lt;li&gt;Throwing an exception: JError::raiseError( 404, JText::_('ALERTNOTAUTH') );&lt;/li&gt;&lt;/ol&gt;You can be fancy and create a function to throw dynamic errors from this if you wish.  It would be best if you put this function in some sort of static method site-wide, but I still haven't found a way to create site-wide custom classes or libraries (e.g. JSite, JRequest, etc)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-8864846771438846600?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/8864846771438846600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/joomla-exceptions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/8864846771438846600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/8864846771438846600'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/joomla-exceptions.html' title='Joomla Exceptions'/><author><name>Carey Hinoki</name><uri>http://www.blogger.com/profile/14192349328683858918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-2498263493243724319</id><published>2009-10-22T17:25:00.000-07:00</published><updated>2009-10-22T17:25:22.017-07:00</updated><title type='text'>FireWorks CS 4 XHTML &amp; CSS Export Function - It Works! Here's how...</title><content type='html'>Well, actually, it's been many years since I seriously tried FireWorks for prototyping websites and generating template code... I gave up on earlier versions, then just sliced and coded by hand.&lt;br /&gt;&lt;br /&gt;But the advent of FireWorks CS4 promises the ability to export in valid XHTML 1.0 Transitional code and quality CSS... so I thought, what the hay, let's give it another shot.&lt;br /&gt;&lt;br /&gt;And it's pretty good!&lt;br /&gt;&lt;br /&gt;Yes, you DO have to follow a set of best practices to get optimal results, but they're all reasonable, understandable, and relatively easy to implement.&lt;br /&gt;&lt;br /&gt;Here's the beauty... FireWorks CS4 now recognizes blocks of text as just that, blocks of text. You no longer have to slice them out as graphics and then replace the guts later. In fact, FireWorks CS4 now does a great job of recognizing "space" in general.&lt;br /&gt;&lt;br /&gt;Essentially now, you just slice your graphics, but leave your text and your blank spaces, and FireWorks CS4 will export quality XHTML with relative positioned CSS if you follow some best practices like:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Do not allow your element containers to overlap (otherwise FireWorks CS4 will output absolute positioned div's).&lt;/li&gt;&lt;li&gt;Let your element container widths be consistent. For instance, if you're prototyping a left column with a content area of 150px with 5px margins, make sure all the text blocks you put in the column are 140px wide, even if it's just a one word header. This is so that when you export, the container div that gets created will have the proper width value, and if you happen to turn that one-word header into two, the second word won't break to the next line.&lt;/li&gt;&lt;li&gt;Use Guides. The guides let you set up the margins and paddings of your document, and give you consistent lines to snap to when placing elements.&lt;/li&gt;&lt;li&gt;Use the FireWorks naming conventions. Now, you can take any text object, and preface it's name with a tag, and when exported, that text element will be wrapped with that tag, with the ID being the text object's given name. Only certain tags work, the default tag is a P tag.&lt;/li&gt;&lt;li&gt;Use background containers. If you draw a rectangle, and then put text &amp;amp; symbols on top of it. FireWorks CS4 generates a container div the size of that rectangle, and all elements within it become subordinates of that container. (Hmm, I haven't tried if elements are only partially within the rectangle.)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Those just a few general hints to get your documents looking right. Adobe provides some great, more in-depth tutorials. &lt;a href="http://www.adobe.com/devnet/fireworks/articles/fireworks_web_design_css.html"&gt;Here is an excellent tutorial that can take you step by step if the above isn't clear. &lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-2498263493243724319?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/2498263493243724319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/fireworks-cs-4-xhtml-css-export.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/2498263493243724319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/2498263493243724319'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/fireworks-cs-4-xhtml-css-export.html' title='FireWorks CS 4 XHTML &amp; CSS Export Function - It Works! Here&apos;s how...'/><author><name>ndrtek</name><uri>http://www.blogger.com/profile/01779131195591843080</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_ckDnExDhLgc/Ssuw7SZgd4I/AAAAAAAAAAM/e9ipBMcNrwc/S220/IT.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-711013599850559770</id><published>2009-10-22T10:54:00.000-07:00</published><updated>2009-10-22T10:55:30.474-07:00</updated><title type='text'>Watch your fonts</title><content type='html'>I’m writing this, so that in the future we may all be on the same page when it comes to choosing the right font for the body text of new developments. I’m sure I don’t need to go into why you need to use web safe fonts… so I want to focus on which are the best of the web safe fonts and why to use them. &lt;br /&gt;&lt;br /&gt;Let’s start of with a list of basic web safe fonts:&lt;br /&gt;&lt;br /&gt;Serif fonts:&lt;br /&gt;&lt;br /&gt;Times New Roman&lt;br /&gt;Times New Roman is a Windows serif font that looks like something you'd see in a newspaper or magazine. It's specially hinted for easier reading on-screen, but Microsoft's free font Georgia is really a better typeface for the screen.&lt;br /&gt;&lt;br /&gt;Times&lt;br /&gt;Times is a Mac serif font. It's similar to Times New Roman, but it isn't as carefully designed for on-screen viewing.&lt;br /&gt;&lt;br /&gt;Georgia&lt;br /&gt;Georgia is a Microsoft's serif face. It's much easier to read on screen than other serif Web fonts because it was designed for the screen.&lt;br /&gt;Georgia has excellent italics that are easy to read and attractive.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Sans Serif fonts:&lt;br /&gt;&lt;br /&gt;Arial&lt;br /&gt;Arial is a Windows sans serif font that has a streamlined, more modern look, but isn't easy to read on screen because it's narrow and can look very light in smaller sizes.&lt;br /&gt;&lt;br /&gt;Helvetica&lt;br /&gt;Helvetica is a Mac sans serif font similar to Arial.&lt;br /&gt;&lt;br /&gt;Verdana&lt;br /&gt;Verdana is an extremely easy-to-read sans serif font that's included with the Internet Explorer. It was designed for the screen.&lt;br /&gt;&lt;br /&gt;Tahoma&lt;br /&gt;Tahoma comes with Microsoft Office and is almost identical to Verdana.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Conclusion: &lt;br /&gt;If you are working on an existing site that has an established font that the user is used to, go with it. But for all new developments, please use Verdana as the first choice (default) for all body text. Should the client request a serif font, please use Georgia. The reason is simple… as you can see above both fonts where designed for on screen and therefore deliver better readability.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-711013599850559770?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/711013599850559770/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/watch-your-fonts.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/711013599850559770'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/711013599850559770'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/watch-your-fonts.html' title='Watch your fonts'/><author><name>Dre</name><uri>http://www.blogger.com/profile/16368104993194304212</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-8865917155672958009</id><published>2009-10-15T16:13:00.000-07:00</published><updated>2009-10-15T16:16:06.063-07:00</updated><title type='text'>Ideal page width for new web design projects</title><content type='html'>Ideal page width for new web design projects&lt;br /&gt;&lt;br /&gt;I started doing some research about this topic after a recent discussion with Will, when he told me that he had to reduce the page width of ACFA to 960 instead of a 1000 pixels. &lt;br /&gt;&lt;br /&gt;After reading some forums / blogs on the topic, it seems like 960px is the assumed optimum width for the majority of web designers. This takes in consideration space for scroll bars. Several other design / development companies have published articles (like this one: &lt;a href="http://www.diginovations.com/web-video-expert/2009/9/9/its-time-to-re-think-the-ideal-page-width-for-web-design.html"&gt;http://www.diginovations.com/web-video-expert/2009/9/9/its-time-to-re-think-the-ideal-page-width-for-web-design.html&lt;/a&gt;) based on raw data extracted mostly form Google Analytics, to make 960 pixels the new minimum page width. &lt;br /&gt;&lt;br /&gt;It is important to consider, that there is still a small but resistant group of “conservative” designers, which believes 775px is the ideal width. Their argument: some people don’t browse with their browser maximized, plus they might have their favorites / history open or other plug-ins such as toolbars taking up additional space.&lt;br /&gt;&lt;br /&gt;Interesting….&lt;br /&gt;&lt;br /&gt;d&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-8865917155672958009?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/8865917155672958009/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/ideal-page-width-for-new-web-design.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/8865917155672958009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/8865917155672958009'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/ideal-page-width-for-new-web-design.html' title='Ideal page width for new web design projects'/><author><name>Dre</name><uri>http://www.blogger.com/profile/16368104993194304212</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-4685988863073429961</id><published>2009-10-15T10:13:00.000-07:00</published><updated>2009-10-15T10:56:49.525-07:00</updated><title type='text'>use your webserver to process php cronjob scripts</title><content type='html'>&lt;span style="font-family:trebuchet ms;"&gt;Ever wish you could run php cronjobs on a webserver without running the script in cgi mode? cgi mode adds another layer of complexity. If your webserver itself runs the script, then you know as long as your server is up, it's processing your cronjobs. Or perhaps maybe you're on a server that doesn't have php cgi available.&lt;br /&gt;If your server is running on Linux, you can use 'wget'  to call your scripts and redirect the output to null. Here's an example:&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;0 12 * * * wget -O /dev/null http://localhost/myscript.php&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:trebuchet ms;"&gt;And if needed, you can also pass query string args as usual:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;0 12 * * * wget -O /dev/null http://localhost/myscript.php?hour=12&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; 0 18 * * * wget -O /dev/null http://localhost/myscript.php?hour=18&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-4685988863073429961?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/4685988863073429961/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/ever-wish-you-could-run-php-cronjobs-on.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/4685988863073429961'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/4685988863073429961'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/ever-wish-you-could-run-php-cronjobs-on.html' title='use your webserver to process php cronjob scripts'/><author><name>Brian Miller</name><uri>http://www.blogger.com/profile/11567586415437722452</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-3373458469122710819</id><published>2009-10-14T22:37:00.001-07:00</published><updated>2009-10-15T16:41:46.066-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='symfony file validator'/><category scheme='http://www.blogger.com/atom/ns#' term='php fileinfo mime'/><category scheme='http://www.blogger.com/atom/ns#' term='mime type validation'/><category scheme='http://www.blogger.com/atom/ns#' term='symfony mime'/><category scheme='http://www.blogger.com/atom/ns#' term='mime type'/><category scheme='http://www.blogger.com/atom/ns#' term='file upload mime'/><category scheme='http://www.blogger.com/atom/ns#' term='php magic file'/><title type='text'>Symfony MIME Type File Validation</title><content type='html'>&lt;a href="http://www.symfony-project.org/book/1_2/10-Forms#chapter_10_sub_standard_symfony_validators"&gt;&lt;br /&gt;http://www.symfony-project.org/book/1_2/10-Forms#chapter_10_sub_standard_symfony_validators&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;(scroll down to sfFileValidator)&lt;br /&gt;&lt;br /&gt;Be careful relying on the MIME type validation of the File Validator in Symfony. The MIME type of the file actually comes from the browser (aka user) as part of the upload.&lt;br /&gt;&lt;br /&gt;As I'm sure you already know, this (and any) user data should not be entirely trusted! Just because it passed the &lt;span style="font-style: italic;"&gt;"image/jpeg"&lt;/span&gt; MIME test does not mean it's a JPEG image.&lt;br /&gt;&lt;br /&gt;In addition, if you're planning on validating uploads like FLV files then you'll be in for a headache with the different MIME types that browsers will throw at you. Further muddling this mess is that if the browser can't determine what it is then it gets sent as a generic &lt;span style="font-style: italic;"&gt;"application/octet-stream"&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Your easiest bet for these two problems is to detect the file's MIME type yourself. This way you're reasonably sure it is what it should be and you now have a consistent (hopefully single) MIME type to test against. &lt;span style="font-weight: bold;"&gt;(View notice below!)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;One such solution could be PHP's &lt;a href="http://www.php.net/fileinfo"&gt;Fileinfo extension&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;BEWARE: Your validation routine is not complete!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The reason why is that the MIME detection is only a method of &lt;span style="font-weight: bold; font-style: italic;"&gt;detection&lt;/span&gt;, it is &lt;span style="font-weight: bold;"&gt;not&lt;/span&gt; a method of &lt;span style="font-style: italic; font-weight: bold;"&gt;validation&lt;/span&gt;. The issue is that the MIME detection only tests particular parts of a file, such as the first few bytes, to determine its type. This is commonly done via a &lt;a href="http://en.wikipedia.org/wiki/Magic_number_%28programming%29#Magic_numbers_in_files"&gt;&lt;span style="font-style: italic;"&gt;magic file&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This does &lt;span style="font-weight: bold;"&gt;not&lt;/span&gt; test that the file is a legitimate GIF image for instance. It could very well be corrupt, and even downright malicious (&lt;a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2004-0200"&gt;CVE-2004-0200&lt;/a&gt; comes to mind).&lt;br /&gt;&lt;br /&gt;For a more thorough image validation, you can attempt to open the image with GD and see if it chokes. Also, ImageMagick's &lt;a href="http://www.imagemagick.org/script/identify.php"&gt;&lt;span style="font-style: italic;"&gt;identify&lt;/span&gt; application&lt;/a&gt; is available.&lt;br /&gt;&lt;br /&gt;However, once again, this will probably not test for a malicious image. This level of security checking requires specialized detection routines that need to be kept up to date. They can be installed with special applications (&lt;a href="http://www.snort.org/"&gt;Snort&lt;/a&gt;), Perl scripts, or even PHP functions that simply detect a special byte ordering.&lt;br /&gt;&lt;br /&gt;Protect your website and your users.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Note: Although I focused on Symfony and images for the examples, the same level of security should be applied to all user uploads.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Note: Symfony 1.2 attempts to locate &lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;finfo_open&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; and &lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;mime_content_type&lt;/span&gt;&lt;span style="font-weight: bold;"&gt;, and the &lt;/span&gt;&lt;span style="font-style: italic; font-weight: bold;"&gt;file &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;tool in sfValidatorFile validator. However if none are found, then it still uses the browser-provided MIME.&lt;/span&gt;&lt;br /&gt;&lt;h2&gt;&lt;/h2&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-3373458469122710819?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/3373458469122710819/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/symfony-mime-type-file-validation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/3373458469122710819'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/3373458469122710819'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/symfony-mime-type-file-validation.html' title='Symfony MIME Type File Validation'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-8962108526000636056</id><published>2009-10-13T17:30:00.000-07:00</published><updated>2009-10-14T20:57:28.070-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cloud infrastructure'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud hosting'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud application'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud computing'/><category scheme='http://www.blogger.com/atom/ns#' term='cloud platform'/><title type='text'>The Cloud: Brief Overview</title><content type='html'>The term "cloud" is used to portray an image of abstraction from the internal infrastructure. From there you attach a word to describe your services such as "cloud computing" or "cloud hosting".&lt;br /&gt;&lt;br /&gt;Clouds have roughly three levels of offerings:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Application&lt;/li&gt;&lt;li&gt;Platform&lt;/li&gt;&lt;li&gt;Infrastructure&lt;/li&gt;&lt;/ul&gt;Depending on your degree of control determines which level you're offered.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Application level&lt;/span&gt; provides only the application for you to use. It's appearance could be just a website, the fact that it's running on "the cloud" is almost completely unknown to the consumer.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Platform level&lt;/span&gt; provides you an area to run your programs that sometimes have to be made "cloud aware" or "cloud compatible" with that service provider. Offerings such as &lt;a href="http://www.rackspacecloud.com/cloud_hosting_products/sites"&gt;Rackspace Cloud Sites&lt;/a&gt; will just appear as simple shared hosting.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Infrastructure level&lt;/span&gt; provides a logical server or other "hardware" devices such as a managed switch. You can control the actual server services and configuration thus allowing you to install applications like &lt;a href="http://gearman.org/"&gt;gearmand&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Examples:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Application - &lt;a href="http://www.salesforce.com/"&gt;Salesforce.com&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Platform - &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Infrastructure - &lt;a href="http://aws.amazon.com/ec2/"&gt;Amazon EC2&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Currently with non-cloud hosting such as Ender's &lt;a href="http://www.endertechnology.com/web-hosting.html"&gt;Los Angeles shared hosting&lt;/a&gt;, only bandwidth was an important measurement. However, with cloud offerings an additional important measurement is "compute cycles" (essentially CPU usage) used by the applications making application optimization an important consideration beyond just Quality of Service.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-8962108526000636056?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/8962108526000636056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/cloud-brief-overview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/8962108526000636056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/8962108526000636056'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/cloud-brief-overview.html' title='The Cloud: Brief Overview'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-1531499037138697459</id><published>2009-10-12T17:15:00.000-07:00</published><updated>2009-10-13T11:12:43.530-07:00</updated><title type='text'>Google translator needs a human touch</title><content type='html'>Soon I will be translating &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Ender&lt;/span&gt; Technology's web site to Spanish.  There are some technical terms that I need to get familiar with so I have started doing my research and started playing with Google's translator.  Google translator can be very useful when translating a word and even phrases but I am not sure about full sentences.  For instance, our home page reads: ' Welcome,  Ender Technology is a &lt;strong&gt;Los Angeles web development company&lt;/strong&gt; providing a broad range of technology services from &lt;strong&gt;simple web design&lt;/strong&gt; to the &lt;strong&gt;planning and development&lt;/strong&gt; of &lt;strong&gt;complex web applications&lt;/strong&gt;.'  I used the &lt;a href="http://translate.google.com"&gt;google translator&lt;/a&gt; to translate this text to Spanish and I got: 'Bienvenido, Ender La tecnología es un desarrollo de Los Angeles web de la compañía proporciona una amplia gama de servicios de tecnología de diseño de páginas web sencillas a la planificación y desarrollo de aplicaciones web complejas.' Uh huh??  If you speak Spanish, you might be able to understand the message after reading it ten times but is anyone going to spend that extra energy on trying to understand the text in a website? I really doubt it.&lt;br /&gt;&lt;br /&gt;This tool is definitely useful to find out how to say/write a word in another language but if you are going to implement it in your site I would reconsider it.  Translating is not the same as interpretating and in order to interpret a message there needs to be a human touch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-1531499037138697459?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/1531499037138697459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/google-translator-needs-human-touch.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/1531499037138697459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/1531499037138697459'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/google-translator-needs-human-touch.html' title='Google translator needs a human touch'/><author><name>Harumi</name><uri>http://www.blogger.com/profile/03390083379341685610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-6498145345260055390</id><published>2009-10-11T02:18:00.000-07:00</published><updated>2009-10-11T02:18:24.959-07:00</updated><title type='text'>The Best Open Source Live Chat for Websites</title><content type='html'>I just discovered &lt;a href="http://www.craftysyntax.com/"&gt;Crafty Syntax&lt;/a&gt; this past week in looking for a Live Chat solution for our corporate site.&lt;br /&gt;&lt;br /&gt;I checked out a few others, &lt;a href="http://www.volusion.com/"&gt;Volusion&lt;/a&gt;'s Joomla plugin, as well as the &lt;a href="http://chatango.com/"&gt;Chatango&lt;/a&gt; Joomla plugin... but:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Volusion's solution is really just a loss leader to get you to buy their commercial version. The free version is woefully under - featured.&lt;/li&gt;&lt;li&gt;Chatango is simply janky.&lt;/li&gt;&lt;/ul&gt;Both solutions require desktop software to be installed, which I'm not too fond of.&lt;br /&gt;&lt;br /&gt;Crafty Syntax on the otherhand, is totally free (though I did donate), and completely web based. It has an automated setup process, and lots of configuration options. It basically provides everything the commercial version of Volusion does... albeit, in a not-quite-so-sexy interface.&lt;br /&gt;&lt;br /&gt;My favorite features include:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Referrer reporting (where did your user get to your site from? what keyword?)&lt;/li&gt;&lt;li&gt;Page tracking (what path did the user take through your site?)&lt;/li&gt;&lt;li&gt;Chat invite &amp;amp; auto-invite&lt;/li&gt;&lt;/ul&gt;And of course, all design / graphical aspects are totally customizable so you can make it suit your brand.&lt;br /&gt;&lt;br /&gt;I'm not sure how effective a website live chat will be to boost sales with a boutique web development shop like ours, but I'll give it a try and we'll see.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-6498145345260055390?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/6498145345260055390/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/best-open-source-live-chat-for-websites.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6498145345260055390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6498145345260055390'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/best-open-source-live-chat-for-websites.html' title='The Best Open Source Live Chat for Websites'/><author><name>ndrtek</name><uri>http://www.blogger.com/profile/01779131195591843080</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_ckDnExDhLgc/Ssuw7SZgd4I/AAAAAAAAAAM/e9ipBMcNrwc/S220/IT.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-6084801290713875820</id><published>2009-10-11T02:07:00.000-07:00</published><updated>2009-10-11T02:07:27.306-07:00</updated><title type='text'>Google Results Depend on Whether You're Logged In</title><content type='html'>Just an FYI for those of you who haven't already noticed, but Google results seem to differ depending on whether you're logged in to Google or not.&lt;br /&gt;&lt;br /&gt;For instance, when I search "los angeles web design" and I'm logged in, my site, EnderTechnology.com, comes up #1!!! But, if I log out and do that same search, we're like on page 3.&lt;br /&gt;&lt;br /&gt;Super annoying, because now I can't trust the results if I'm trying to do a search engine analysis. I have to open a window with a separate logged out session. I wonder why / how they are doing this?&lt;br /&gt;&lt;br /&gt;Perhaps it occurs only if you have the Google Toolbar installed, because clearly they're tracking which websites I've visited most, and giving some kind of preferences to those in their rankings.&lt;br /&gt;&lt;br /&gt;Don't like it...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-6084801290713875820?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/6084801290713875820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/google-results-depend-on-whether-youre.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6084801290713875820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/6084801290713875820'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/google-results-depend-on-whether-youre.html' title='Google Results Depend on Whether You&apos;re Logged In'/><author><name>ndrtek</name><uri>http://www.blogger.com/profile/01779131195591843080</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_ckDnExDhLgc/Ssuw7SZgd4I/AAAAAAAAAAM/e9ipBMcNrwc/S220/IT.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-161415255433400592</id><published>2009-10-09T11:49:00.000-07:00</published><updated>2009-10-09T11:58:39.506-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google earth plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='google earth overlay'/><category scheme='http://www.blogger.com/atom/ns#' term='google earth iframe shim'/><category scheme='http://www.blogger.com/atom/ns#' term='google earth div'/><category scheme='http://www.blogger.com/atom/ns#' term='google earth div iframe'/><title type='text'>Google Earth DIV Overlay via Iframe Shim</title><content type='html'>Need to create a div overlay on top of a Google Earth browser plugin rendering?&lt;br /&gt;&lt;br /&gt;Use an &lt;span style="font-weight: bold;"&gt;iframe shim&lt;/span&gt; and load it &lt;span style="font-weight: bold;"&gt;AFTER &lt;/span&gt;the GE has rendered!&lt;br /&gt;&lt;br /&gt;Use a timeout or render it when via a GE event such as a balloon click.&lt;br /&gt;&lt;br /&gt;Unfortunately, it appears that transparency does not work with the overlay.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-161415255433400592?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/161415255433400592/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/google-earth-div-overlay-via-iframe.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/161415255433400592'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/161415255433400592'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/google-earth-div-overlay-via-iframe.html' title='Google Earth DIV Overlay via Iframe Shim'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-244857565499412295</id><published>2009-10-07T16:34:00.000-07:00</published><updated>2009-10-14T11:54:22.192-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='symfony 1.0'/><category scheme='http://www.blogger.com/atom/ns#' term='symfony'/><category scheme='http://www.blogger.com/atom/ns#' term='symfony plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='template'/><category scheme='http://www.blogger.com/atom/ns#' term='twig'/><category scheme='http://www.blogger.com/atom/ns#' term='symfony 2.0'/><title type='text'>New template engine for Symfony?</title><content type='html'>&lt;a href="http://fabien.potencier.org/article/34/templating-engines-in-php"&gt;http://fabien.potencier.org/article/34/templating-engines-in-php&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Will Twig be integrated with Symfony 2.0? Maybe a plugin for 1.0+?&lt;br /&gt;&lt;br /&gt;The Symfony templating component has already been released:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://components.symfony-project.org/templating/"&gt;http://components.symfony-project.org/templating/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Twig will probably will remain as its own project like Propel and Doctrine.&lt;br /&gt;&lt;br /&gt;I wonder if Fabien's Smarty benchmarks used the compiled templates.&lt;br /&gt;&lt;br /&gt;Edit 2009-10-12: Fixed my ramblings with descriptions&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-244857565499412295?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/244857565499412295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/new-template-engine-for-symfony.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/244857565499412295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/244857565499412295'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/new-template-engine-for-symfony.html' title='New template engine for Symfony?'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-1219194622159095843</id><published>2009-10-06T16:37:00.000-07:00</published><updated>2009-10-06T18:48:20.658-07:00</updated><title type='text'>Symfony 1.2 Pagination Max Per Page Selection</title><content type='html'>With symfony 1.2, it is fairly easy to paginate a list of results with the sfPager object, but not every nicety is given.&lt;br /&gt;&lt;br /&gt;Here is a simple PaginationMaxPerPageForm class using the symfony 1.2 form framework:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;class PaginationMaxPerPageForm extends sfForm&lt;br /&gt;{&lt;br /&gt; protected&lt;br /&gt;   $user = null;&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Constructor.&lt;br /&gt;  *&lt;br /&gt;  * @param sfUser A sfUser instance&lt;br /&gt;  * @param array  An array of options&lt;br /&gt;  * @param string A CSRF secret (false to disable CSRF protection, null to use the global CSRF secret)&lt;br /&gt;  *&lt;br /&gt;  * @see sfForm&lt;br /&gt;  */&lt;br /&gt; public function __construct(sfUser $user, $options = array(), $CSRFSecret = null)&lt;br /&gt; {&lt;br /&gt;   $this-&gt;user = $user;&lt;br /&gt;&lt;br /&gt;   parent::__construct(array(), $options, $CSRFSecret);&lt;br /&gt;&lt;br /&gt;   // the defaults depend on the options, so set them after construction&lt;br /&gt;   $this-&gt;setDefaults(array('max_per_page' =&gt; $user-&gt;getAttribute(self::getMaxPerPageName(), self::getMaxPerPageValue())));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Changes the current max_per_page attribute.&lt;br /&gt;  */&lt;br /&gt; public function save()&lt;br /&gt; {&lt;br /&gt;   $this-&gt;user-&gt;setAttribute(self::getMaxPerPageName(), $this-&gt;getValue('max_per_page'));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; /**&lt;br /&gt;  * Processes the current request.&lt;br /&gt;  *&lt;br /&gt;  * @param  sfRequest A sfRequest instance&lt;br /&gt;  *&lt;br /&gt;  * @return Boolean   true if the form is valid, false otherwise&lt;br /&gt;  */&lt;br /&gt; public function process(sfRequest $request)&lt;br /&gt; {&lt;br /&gt;   $data = array('max_per_page' =&gt; $request-&gt;getParameter('max_per_page', $this-&gt;user-&gt;getAttribute(self::getMaxPerPageName(), $this-&gt;getDefault('max_per_page'))));&lt;br /&gt;   if ($request-&gt;hasParameter(self::$CSRFFieldName))&lt;br /&gt;   {&lt;br /&gt;     $data[self::$CSRFFieldName] = $request-&gt;getParameter(self::$CSRFFieldName);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   $this-&gt;bind($data);&lt;br /&gt;&lt;br /&gt;   if ($isValid = $this-&gt;isValid())&lt;br /&gt;   {&lt;br /&gt;     $this-&gt;save();&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return $isValid;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public function configure()&lt;br /&gt; {&lt;br /&gt;   $this-&gt;setWidgets(array(&lt;br /&gt;     'max_per_page' =&gt; new sfWidgetFormSelect(array(&lt;br /&gt;       'choices' =&gt; self::getMaxPerPageChoices(),&lt;br /&gt;     )),&lt;br /&gt;   ));&lt;br /&gt;&lt;br /&gt;   $this-&gt;setValidators(array(&lt;br /&gt;     'max_per_page' =&gt; new sfValidatorChoice(array(&lt;br /&gt;       'choices' =&gt; array_keys(self::getMaxPerPageChoices()),&lt;br /&gt;       'required' =&gt; false,&lt;br /&gt;     )),&lt;br /&gt;   ));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected function getMaxPerPageChoices()&lt;br /&gt; {&lt;br /&gt;   if (&lt;br /&gt;     isset($this-&gt;options['max_per_page_choices'])&lt;br /&gt;     &amp;amp;&amp;amp;&lt;br /&gt;     is_array($this-&gt;options['max_per_page_choices'])&lt;br /&gt;     &amp;amp;&amp;amp;&lt;br /&gt;     !empty($this-&gt;options['max_per_page_choices'])&lt;br /&gt;   )&lt;br /&gt;   {&lt;br /&gt;     return $this-&gt;options['max_per_page_choices'];&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return array(&lt;br /&gt;     5 =&gt; 5,&lt;br /&gt;     10 =&gt; 10,&lt;br /&gt;     25 =&gt; 25,&lt;br /&gt;     50 =&gt; 50,&lt;br /&gt;   );&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected function getMaxPerPageName()&lt;br /&gt; {&lt;br /&gt;   if (&lt;br /&gt;     isset($this-&gt;options['max_per_page_name'])&lt;br /&gt;     &amp;amp;&amp;amp;&lt;br /&gt;     is_string($this-&gt;options['max_per_page_name'])&lt;br /&gt;     &amp;amp;&amp;amp;&lt;br /&gt;     !empty($this-&gt;options['max_per_page_name'])&lt;br /&gt;   )&lt;br /&gt;   {&lt;br /&gt;     return $this-&gt;options['max_per_page_name'];&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return 'pager_max_per_page';&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; protected function getMaxPerPageValue()&lt;br /&gt; {&lt;br /&gt;   if (&lt;br /&gt;     isset($this-&gt;options['max_per_page_value'])&lt;br /&gt;     &amp;amp;&amp;amp;&lt;br /&gt;     is_numeric($this-&gt;options['max_per_page_value'])&lt;br /&gt;     &amp;amp;&amp;amp;&lt;br /&gt;     !empty($this-&gt;options['max_per_page_value'])&lt;br /&gt;   )&lt;br /&gt;   {&lt;br /&gt;     return intval($this-&gt;options['max_per_page_value']);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return 10;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With this code in your project's lib/form/PaginationMaxPerPageForm.class.php file, you can create the following in a template:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;$form = new PaginationMaxPerPageForm($sf_user, array(), false);&lt;br /&gt;$form-&gt;process($sf_request);&lt;br /&gt;&lt;br /&gt;echo $form-&gt;renderFormTag(url_for($sf_request-&gt;getUri()), array(&lt;br /&gt;  'method' =&gt; 'get',&lt;br /&gt;));&lt;br /&gt;?&amp;gt;&lt;br /&gt;&amp;lt;div class="max_per_page"&amp;gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;echo $form-&gt;renderGlobalErrors();&lt;br /&gt;echo $form-&gt;renderHiddenFields();&lt;br /&gt;&lt;br /&gt;if ($sf_request-&gt;getParameter('page')) : ?&amp;gt;&lt;br /&gt;&amp;lt;input type="hidden" name="&amp;lt;?php echo 'page' ?&amp;gt;" value="&amp;lt;?php echo $sf_request-&gt;getParameter('page') ?&amp;gt;" /&amp;gt;&lt;br /&gt;&amp;lt;?php endif;&lt;br /&gt;&lt;br /&gt;echo 'Show';&lt;br /&gt;&lt;br /&gt;echo $form['max_per_page']-&gt;render(array('onchange' =&gt; 'this.form.submit()'));&lt;br /&gt;echo $form['max_per_page']-&gt;renderLabel('items per page');&lt;br /&gt;echo $form['max_per_page']-&gt;renderError();&lt;br /&gt;?&amp;gt;&lt;br /&gt;&amp;lt;noscript&amp;gt;&amp;lt;input type="submit" value="Submit" /&amp;gt;&amp;lt;/noscript&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;NOTE:&lt;/span&gt; the above url_for() value in the renderFormTag() assumes you will be submitting the form to the current page URL.&lt;br /&gt;&lt;br /&gt;In the related template's action class (which should have a pager object), you can check for the max per page value with something like the following:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;$max_per_page = $request-&gt;getParameter('max_per_page', $this-&gt;getUser()-&gt;getAttribute('pager_max_per_page', 10));&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Don't forget, you can customize some of the values used by the PaginationMaxPerPageForm by setting some options in the second parameter array, like:&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;$form = new PaginationMaxPerPageForm($sf_user, array(&lt;br /&gt;  'max_per_page_name' =&amp;gt; 'myMaxPageVar',&lt;br /&gt;  'max_per_page_value' =&amp;gt; 100,&lt;br /&gt;  'max_per_page_choices' =&amp;gt; array(&lt;br /&gt;    10 =&amp;gt; 10,&lt;br /&gt;    50 =&amp;gt; 50,&lt;br /&gt;    100 =&amp;gt; 100,&lt;br /&gt;    150 =&amp;gt; 150,&lt;br /&gt;  ),&lt;br /&gt;), false);&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So simple.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-1219194622159095843?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/1219194622159095843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/symfony-12-pagination-max-per-page.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/1219194622159095843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/1219194622159095843'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/symfony-12-pagination-max-per-page.html' title='Symfony 1.2 Pagination Max Per Page Selection'/><author><name>Willem Luijt</name><uri>http://www.blogger.com/profile/13997538282134693132</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-632166815173680552</id><published>2009-10-06T15:07:00.000-07:00</published><updated>2009-10-06T16:05:09.044-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flash portfolio'/><category scheme='http://www.blogger.com/atom/ns#' term='web design trends'/><title type='text'>Visually stunning portfolios</title><content type='html'>I figured I would cover visual topics…&lt;br /&gt;So let’s kick it off with some visually stunning pieces. They are all flash driven photographers’ portfolios. Not only is the design of the flash player very clean, minimalist with an eye to avoid clutter, but also the content is visually appealing. So besides highlighting a current trend in flash design, these sites showcase another important hurdle we often face in the visual component of web design: the content has to be good for the site to rock! Let’s enjoy the following, even though we may have to deal with a bit of load time…&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.jamesdayphoto.com/"&gt;http://www.jamesdayphoto.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.steffenjahn.com/publish/html/index.html"&gt;http://www.steffenjahn.com/publish/html/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.shuakashi.com/"&gt;http://www.shuakashi.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Check out the Gordon Ramsey picture under Fame&lt;br /&gt;&lt;a href="http://www.johnwrightphoto.com/"&gt;http://www.johnwrightphoto.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-632166815173680552?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/632166815173680552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/visually-stunning-portfolios.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/632166815173680552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/632166815173680552'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/visually-stunning-portfolios.html' title='Visually stunning portfolios'/><author><name>Dre</name><uri>http://www.blogger.com/profile/16368104993194304212</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-4440437540226086466</id><published>2009-10-06T14:05:00.000-07:00</published><updated>2009-10-06T15:20:43.538-07:00</updated><title type='text'>Foomla Jail?</title><content type='html'>I spent my last two Monday nights, till the wee hours mind you, trying to finish a custom Joomla Component.  I am creating a Flash game component for my site oghead.com.  The component will allow images and flash files to be uploaded and will be categorically displayed on the corresponding frontend page.  Easy right?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Wrong...  Creating a component for Joomla is the most taxing thing that you can do in Joomla.  Joomla offers terrible documentation and guidance for creating components.  Since Joomla is so extension driven, it is a shame to see such poor implementation practices.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In my last two programming sessions, I was trying to install a system for uploading flash files and their images.  The files had to be uploaded to specific directories that may or may not have to be created.  The directory structure I created was a file name based system.  However, this posed some problems.  If you try and rename a file to one in which was already taken, you would either A, not be able to do it, or B, overwrite what was already there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I had to come up with another alternative.  Now... each directory is based off of a file name structure consisting of id_name.  This fixed the problem posed earlier.  To supplement this change I had to implement a routine to move the directory based on the changing files names. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;...All fine and dandy, but this was barely a dent into the component itself.  I was expecting for libraries to handle most of this...  So.. moving onto the code... &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Joomla does have some basic file and folder libraries, however, they do not work properly, or did not in my instance.  Since the libraries were spitting out incorrect values, I was left to hand coding an implementation.   I ended up having to use base php functions such as @mkdir, move_uploaded_files, file_exists, and rename.  This wasn't really a problem, but having to hand code something that should already exist is a pain (time squambler - yes I said squambler).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So after spending so many hours just trying to get file uploading working correctly.  That was just a small segment of what a component is.  To summarize, a component is a large file structure, of possibly useless functions, to house segmented functionality.  Each method Joomla has to offer has to be recoded by hand.  There isn't any predefined methods or functions for handling these measures.  That means I am left with hand coding or copying/altering code to finish off the implementation.  This also poses problems because when implementing all of those ambiguous methods, warnings and notices end up creeping in... and you're like...why?!?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyways... There are some means of creating cookiecutter components, but they are still lacking a gross amount of implementation.  See here.. &lt;a href="http://www.notwebdesign.com/joomla-component-creator/index.php"&gt;http://www.notwebdesign.com/joomla-component-creator/index.php&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This still is a poor option.  Creating a component file structure is terrible enough, but having to implement 40 functions, AGAIN, that should already be defined is just wrong.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Walking through a custom component yourself (creating a complicated one from scratch) is definitely good practice in learning Joomla, I won't argue, but there is definitely a need for autogenerated code.  There are so many functions and methods which seem useless to me.  But with poor documentation, you cannot even begin to fathom Joomla's, perhaps pointless, architectural decisions.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This leaves us with a bit of a dilemma.  Right now my framework options are either Joomla or Symfony.  Use Joomla, have a wide range of extensions (majority of which are subpar and written subpar-ly), and have super slow custom development.  Or use Symfony, have a quicker custom development, but have limited access to extensions....&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If I can harness and create autogenerating components, I think the roughest edges of Joomla should be softened, at least a bit.  So Joomla, you win for now.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-4440437540226086466?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/4440437540226086466/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/foomla-jail.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/4440437540226086466'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/4440437540226086466'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/foomla-jail.html' title='Foomla Jail?'/><author><name>Carey Hinoki</name><uri>http://www.blogger.com/profile/14192349328683858918</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-7006375446852442279</id><published>2009-10-06T13:50:00.000-07:00</published><updated>2009-10-06T15:06:05.576-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delete job'/><category scheme='http://www.blogger.com/atom/ns#' term='dead letter queue'/><category scheme='http://www.blogger.com/atom/ns#' term='gearman'/><category scheme='http://www.blogger.com/atom/ns#' term='poison message'/><category scheme='http://www.blogger.com/atom/ns#' term='gearmand'/><category scheme='http://www.blogger.com/atom/ns#' term='worker die'/><category scheme='http://www.blogger.com/atom/ns#' term='worker'/><category scheme='http://www.blogger.com/atom/ns#' term='worker crash'/><category scheme='http://www.blogger.com/atom/ns#' term='poison job'/><title type='text'>Gearman and Poison Messages/Jobs</title><content type='html'>"Gearman provides a generic application framework to farm out work to other machines or processes that are better suited to do the work." (&lt;a href="http://gearman.org/"&gt;gearman.org&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;gearmand, the server, includes an important feature that should be enabled for all installations:&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-weight: bold;"&gt;&lt;blockquote&gt;-j, --job-retries&lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;This feature protects against poison messages/jobs which is not enabled by default.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;Poison Message&lt;/span&gt;: &lt;span style="font-style: italic;"&gt;A message in the queue that has met the threshold of allowable retries.&lt;/span&gt;&lt;/blockquote&gt;For Gearman, this would be when a worker receives a job but disconnects from the server without advising the job's completion whether success or failure.&lt;br /&gt;&lt;br /&gt;A disconnect can occur due to an error in the worker's processing of a job such as "out of memory", an error in the processing such as a "Segmentation fault" when resizing an image, or even an error in the Gearman PHP extension.&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-weight: bold;font-size:180%;" &gt;    Now why is this important?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;Let's run a scenario:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Worker connects to gearmand&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Worker receives job&lt;/li&gt;&lt;li&gt;Worker begins processing job&lt;/li&gt;&lt;li&gt;Worker dies due to an error and disconnects&lt;/li&gt;&lt;li&gt;Gearmand sesnses disconnect&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Gearmand redispatches job to another worker&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Lather, rinse, repeat until all workers crash&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;If you set &lt;span style="font-weight: bold;"&gt;--job-retries=3&lt;/span&gt; then as soon as the above scenario happens three times, gearmand will delete the message and log the error saving the rest of your workers from similar fate.&lt;br /&gt;&lt;span style="font-size:100%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:100%;" &gt;What if I want to handle that deleted job?&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:78%;" &gt;(for example, emailing the client that their job failed)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/span&gt;Unfortunately, currently, you will have to scan the log looking for deleted jobs and manually handle them.&lt;br /&gt;&lt;br /&gt;However, aligned with Ender Tech's open source commitment, I have submitted a feature request to have the message redispatched to a "Dead Letter Queue" or "Poison Queue":&lt;br /&gt;&lt;br /&gt;&lt;a href="https://bugs.launchpad.net/gearmand/+bug/442539"&gt;https://bugs.launchpad.net/gearmand/+bug/442539&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This way you can assign a worker to handle the dead jobs without scanning the log thereby allowing a fast, robust, and consistent job handling infrastructure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-7006375446852442279?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/7006375446852442279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/gearman-and-poison-messages-or-jobs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/7006375446852442279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/7006375446852442279'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/gearman-and-poison-messages-or-jobs.html' title='Gearman and Poison Messages/Jobs'/><author><name>Rob O.</name><uri>http://www.blogger.com/profile/08167573705184000025</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-5819880777586939966</id><published>2009-10-03T23:37:00.000-07:00</published><updated>2009-10-04T02:10:45.756-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='joomla'/><category scheme='http://www.blogger.com/atom/ns#' term='email form'/><category scheme='http://www.blogger.com/atom/ns#' term='javascript email'/><category scheme='http://www.blogger.com/atom/ns#' term='email cloaking bug'/><title type='text'>Joomla Email Cloak and Email Form Fields Don't Mix</title><content type='html'>Just discovered this slight annoyance with Joomla.&lt;br /&gt;&lt;br /&gt;I was integrating a custom form into a Joomla module using &lt;a href="http://www.fijiwebdesign.com/portfolio/joomla-php-module-mod_php.html"&gt;this cool plugin&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If my form validation logic invalidated the form and re-routed back to the form, where there should be the user's email address echo'd back to him, would be a JavaScript tag that echoes an email address so as to mask it from email harvesting bots.&lt;br /&gt;&lt;br /&gt;Turns out this is on account of the default Joomla 1.5 plugin "Content - Email Cloaking". Disabilng the plugin solves the problem, but then you lose the masking. It would be nice if somehow the plugin could distinguish the context, and if the email addresses is quoted inside a "value" attribute, leave it alone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-5819880777586939966?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/5819880777586939966/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/joomla-email-cloak-and-email-form.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5819880777586939966'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5819880777586939966'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/joomla-email-cloak-and-email-form.html' title='Joomla Email Cloak and Email Form Fields Don&apos;t Mix'/><author><name>ndrtek</name><uri>http://www.blogger.com/profile/01779131195591843080</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_ckDnExDhLgc/Ssuw7SZgd4I/AAAAAAAAAAM/e9ipBMcNrwc/S220/IT.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-5691578230537548572</id><published>2009-10-03T22:56:00.000-07:00</published><updated>2009-10-12T11:49:33.655-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='howto twitter with php'/><category scheme='http://www.blogger.com/atom/ns#' term='php twitter integration'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><category scheme='http://www.blogger.com/atom/ns#' term='php tweet'/><title type='text'>Quick Tweet with PHP - How to integrate Twitter with 20 lines of code</title><content type='html'>I found this tidbit on &lt;a href="http://us2.php.net/manual/en/function.stream-context-create.php"&gt;php.net&lt;/a&gt;. Super quick and easy tweet from within PHP courtesy of &lt;a href="http://fabien.potencier.org/article/20/tweeting-from-php"&gt;Fabien Potencier&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre name="code" class="php"&gt;&amp;lt;?php&lt;br /&gt;function tweet($message, $username, $password)&lt;br /&gt;{&lt;br /&gt;  $context = stream_context_create(array(&lt;br /&gt;    'http' =&amp;gt; array(&lt;br /&gt;      'method'  =&amp;gt; 'POST',&lt;br /&gt;      'header'  =&amp;gt; sprintf("Authorization: Basic %s\r\n", base64_encode($username.':'.$password)).&lt;br /&gt;                   "Content-type: application/x-www-form-urlencoded\r\n",&lt;br /&gt;      'content' =&amp;gt; http_build_query(array('status' =&amp;gt; $message)),&lt;br /&gt;      'timeout' =&amp;gt; 5,&lt;br /&gt;    ),&lt;br /&gt;  ));&lt;br /&gt;  $ret = file_get_contents('http://twitter.com/statuses/update.xml', false, $context);&lt;br /&gt; &lt;br /&gt;  return false !== $ret;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;br /&gt;Pretty easy, no? Using the tweet() function is of course a piece of cake:&lt;br /&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;tweet('From PHP, yeah...', 'fabpot', 'Pa$$');&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-5691578230537548572?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/5691578230537548572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/quick-tweet-with-php-how-to-integrate.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5691578230537548572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/5691578230537548572'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/quick-tweet-with-php-how-to-integrate.html' title='Quick Tweet with PHP - How to integrate Twitter with 20 lines of code'/><author><name>ndrtek</name><uri>http://www.blogger.com/profile/01779131195591843080</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_ckDnExDhLgc/Ssuw7SZgd4I/AAAAAAAAAAM/e9ipBMcNrwc/S220/IT.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3284671458011514265.post-943985334169983292</id><published>2009-10-02T00:33:00.000-07:00</published><updated>2009-10-03T23:16:14.170-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='symfony'/><category scheme='http://www.blogger.com/atom/ns#' term='PHP'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc pattern'/><category scheme='http://www.blogger.com/atom/ns#' term='design patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='object oriented programming'/><title type='text'>Symfony PHP Framework - The Experts Choice</title><content type='html'>I've been building PHP web apps since 1998, and I've built them in all sorts of ways.&lt;br /&gt;&lt;br /&gt;Of course my initial attempts were amateurish, the type of procedural code you see from newbies, but as my experience grew, my techniques became more sophisticated, and my understanding of why advanced techniques were necessary became more clear.&lt;br /&gt;&lt;br /&gt;Before Symfony, I took several shots at my own framework. First, with PHP4, just a loose set of common functions organized around common needs like content management, shopping carts, form processing, etc.&lt;br /&gt;&lt;br /&gt;I quickly discovered the need to automate the creation of forms and form processing logic from database schema, and whipped together a procedural system for that.&lt;br /&gt;&lt;br /&gt;As my company grew, i.e. I started hiring employees, I realized that this loose methodology didn't scale and extend very well. It worked if you built it and you knew how everything worked, but when you had to teach it to others, there just wasn't enough standardization. We needed a better way to collaborate on projects.&lt;br /&gt;&lt;br /&gt;As I was coming to this realization, PHP5 was maturing, and PHP really became an object oriented language.&lt;br /&gt;&lt;br /&gt;Now, I wasn't a programmer by education (my major was Philosophy), but rather a geek by love and by nature, you know, one of those junior high and high school kids who were infatuated by computers and the burgeoning Internet in the 90's. So object oriented programming, design patterns, MVC, and the elements of this paradigm were foreign to me to start.&lt;br /&gt;&lt;br /&gt;Fortunately, an excellent book was recommended to me that really opened my eyes about PHP and object oriented programming, "&lt;a href="http://www.amazon.com/gp/product/1590593804?ie=UTF8&amp;amp;tag=thente-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1590593804"&gt;PHP 5 Objects, Patterns, and Practice&lt;/a&gt;" by Matt Zandstra.&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=thente-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1590593804" style="border: medium none ! important; margin: 0px ! important;" width="1" /&gt; I highly recommend this book to anyone looking to understand the "what's", "why's", and "how's" of PHP 5 OOP programming.&lt;br /&gt;&lt;br /&gt;After reading that, I was inspired to build my own PHP 5 object oriented framework for web applications. At the time, (say, early 2004?), there wasn't anything very mature out there. CakePHP was still really a PHP 4 system, and I hadn't even heard of Symfony (probably in early Alpha at the time) at the time.&lt;br /&gt;&lt;br /&gt;My team and I worked on our own framework for a year or two, building some pretty sophisticated apps for small and mid-sized businesses, and it was a definite improvement over our PHP 4 methods. We learned a lot, and many of those websites are still running today on our framework.&lt;br /&gt;&lt;br /&gt;However, over time, we found our home built framework lacking in features, and discovered &lt;a href="http://www.symfony-project.org/"&gt;Symfony &lt;/a&gt;in late 2007. Symfony was an open source project with a small army of super talented developrs, and was light years ahead of our framework, so we decided to jump on the bandwagon... and thank goodness we did!&lt;br /&gt;&lt;br /&gt;Symfony solved many common challenges the same way we did, for instance automatic form and code generation based upon database schema... but did so more thoroughly, and added a whole bunch on top, not the least of which is fantastic documentation and an awesome beginners guide entitled, "&lt;a href="http://www.amazon.com/gp/product/1590597869?ie=UTF8&amp;amp;tag=thente-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1590597869"&gt;The Definitive Guide to Symfony&lt;/a&gt;" by Fabien Potencier&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=thente-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1590597869" style="border: medium none ! important; margin: 0px ! important;" width="1" /&gt;.&lt;br /&gt;&lt;br /&gt;Now, with 10 web developers collaborating on projects for dozens of clients, we finally had a robust methodology to standardize our company's practices on. Everyone could easily learn the Symfony framework, as there was great documentation available, and tons of utilities and plugins readily available to incorporate into our projects.&lt;br /&gt;&lt;br /&gt;The result has been phenomenal, we are producing the highest quality websites, with the most robust code, very rapidly. Our systems are easily extended by virtue of the clear MVC pattern and code organization practices Symfony enforces. Projects can be collaborated on and exchanged between developers due to the commonality of file organization and standard plugins for common purposes like authentication, permissions, and more.&lt;br /&gt;&lt;br /&gt;As the leader of a boutique web development agency, with over a decade of web development experience under my belt, I highly recommend Symfony as the de facto standard for enterprise class PHP applications.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt;&lt;a href="http://www.symfony-project.org/"&gt;The Symfony Project&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/1590597869?ie=UTF8&amp;amp;tag=thente-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1590597869"&gt;The Definitive Guide to Symfony&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=thente-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1590597869" style="border: medium none ! important; margin: 0px ! important;" width="1" /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/1590593804?ie=UTF8&amp;amp;tag=thente-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1590593804"&gt;PHP 5 Objects, Patterns, and Practice&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=thente-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1590593804" style="border: medium none ! important; margin: 0px ! important;" width="1" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3284671458011514265-943985334169983292?l=endertech.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://endertech.blogspot.com/feeds/943985334169983292/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://endertech.blogspot.com/2009/10/symfony-php-framework-experts-choice.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/943985334169983292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3284671458011514265/posts/default/943985334169983292'/><link rel='alternate' type='text/html' href='http://endertech.blogspot.com/2009/10/symfony-php-framework-experts-choice.html' title='Symfony PHP Framework - The Experts Choice'/><author><name>ndrtek</name><uri>http://www.blogger.com/profile/01779131195591843080</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://3.bp.blogspot.com/_ckDnExDhLgc/Ssuw7SZgd4I/AAAAAAAAAAM/e9ipBMcNrwc/S220/IT.jpg'/></author><thr:total>0</thr:total></entry></feed>
