PageRenderTime 45ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/papers/nyphp-2007-01/index.html

https://github.com/horde/horde-web
HTML | 438 lines | 367 code | 57 blank | 14 comment | 0 complexity | 1879968f229508b1e04e386862f9c4d0 MD5 | raw file
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml">
  4. <head>
  5. <title>Application Building With Horde</title>
  6. <!-- metadata -->
  7. <meta name="generator" content="S5" />
  8. <meta name="version" content="S5 1.1" />
  9. <meta name="presdate" content="2007-01-23" />
  10. <meta name="author" content="Chuck Hagenbuch" />
  11. <!-- configuration parameters -->
  12. <meta name="defaultView" content="slideshow" />
  13. <meta name="controlVis" content="hidden" />
  14. <!-- style sheet links -->
  15. <link rel="stylesheet" href="../s5/ui/slides.css" type="text/css" media="projection" id="slideProj" />
  16. <link rel="stylesheet" href="../s5/ui/outline.css" type="text/css" media="screen" id="outlineStyle" />
  17. <link rel="stylesheet" href="../s5/ui/print.css" type="text/css" media="print" id="slidePrint" />
  18. <link rel="stylesheet" href="../s5/ui/opera.css" type="text/css" media="projection" id="operaFix" />
  19. <!-- S5 JS -->
  20. <script src="../s5/ui/slides.js" type="text/javascript"></script>
  21. <!-- prototype + scriptaculous -->
  22. <script src="../s5/ui/prototype/prototype.js" type="text/javascript"></script>
  23. <script src="../s5/ui/scriptaculous/scriptaculous.js" type="text/javascript"></script>
  24. <!-- Presentaculous JS -->
  25. <script src="../s5/ui/presentacular.js" type="text/javascript"></script>
  26. </head>
  27. <body>
  28. <div class="layout">
  29. <div id="currentSlide"></div>
  30. <div id="header"></div>
  31. <div id="footer">
  32. <h1>New York, New York &#8226; January 23rd 2007</h1>
  33. <h2>Application Building With Horde</h2>
  34. <div id="controls"></div>
  35. </div>
  36. </div>
  37. <div class="presentation">
  38. <div class="slide">
  39. <h1>Application Building With Horde</h1>
  40. <h3>Chuck Hagenbuch</h3>
  41. <h4><a href="http://www.horde.org/">The Horde Project</a></h4>
  42. <div class="handout">
  43. <p>You probably know that Horde does webmail. But Horde also provides a framework for building applications. Chuck Hagenbuch will demonstrate a mix of ORM, prototype + script.aculo.us, and mapping APIs that quickly assemble into an application using Horde (call it a mashup if you must). We'll also demonstrate building standalone pages that incorporate content from an existing Horde installation.</p>
  44. <p>Chuck Hagenbuch founded the Horde Project in 1998 and has been working with PHP and the world of web development ever since. He is currently an independent consultant, and has provided professional services to high-profile PHP users such as PayPal and Portugal Telecom.</p>
  45. </div>
  46. </div>
  47. <div class="slide">
  48. <h1>Syllabus: Horde</h1>
  49. <ul>
  50. <li>What?</li>
  51. <li>Why?</li>
  52. <li>How?</li>
  53. </ul>
  54. </div>
  55. <div class="slide">
  56. <h1>&quot;What is Horde?&quot;</h1>
  57. <ul class="incremental">
  58. <li>The Horde Project: an open source project driven by:</li>
  59. <li>The Horde Developers: volunteer developers providing:</li>
  60. <li>The Horde Application Framework: a PHP web application framework, consisting of:</li>
  61. <li>The Horde Libraries: PEAR-style packages powering:</li>
  62. <li>The Horde Applications: real-world integrated web applications</li>
  63. </ul>
  64. </div>
  65. <div class="slide">
  66. <h1>Why: Libraries</h1>
  67. <ul class="incremental">
  68. <li>Over 60 high quality PHP libraries in PEAR packages</li>
  69. <li>PHP4 and PHP5</li>
  70. <li>Authentication and Permissions to MIME handling to user preferences to XML transformations</li>
  71. <li>Coding standards that were the basis for the PEAR coding standards</li>
  72. <li>Initial PEAR packages including Log and Mail were contributed from Horde to PEAR</li>
  73. </ul>
  74. </div>
  75. <div class="slide">
  76. <h1>Why: Standards</h1>
  77. <ul class="incremental">
  78. <li>XHTML/CSS Layout</li>
  79. <li>Comprehensive MIME standards support</li>
  80. <li>Groupware apps all handle iCalendar and vCard</li>
  81. <li>SOAP and XML-RPC access to all application APIs</li>
  82. <li>SyncML server</li>
  83. <li>WebDAV server</li>
  84. </ul>
  85. </div>
  86. <div class="slide">
  87. <h1>Why: Backend Independence</h1>
  88. <ul class="incremental">
  89. <li>SQL drivers work for MySQL, PostgreSQL, Oracle, MSSQL, more</li>
  90. <li>LDAP support for contacts, preferences, users, more.</li>
  91. <li>VFS (virtual filesystem) support for local files, SQL, FTP, more</li>
  92. <li>Pluggable drivers for all backends</li>
  93. </ul>
  94. </div>
  95. <div class="slide">
  96. <h1>Why: Applications</h1>
  97. <ul class="incremental">
  98. <li>Over 50 in CVS</li>
  99. <li>Used by MIT, Portugal Telecom, and many many more</li>
  100. <li>Groupware apps are all in at least 2nd major release</li>
  101. <li>All applications integrate users and their data</li>
  102. <li>Developer tools including Chora and Whups</li>
  103. <li>Access to APIs without tight coupling</li>
  104. </ul>
  105. </div>
  106. <div class="slide">
  107. <h1>Why: Internationalization</h1>
  108. <ul class="incremental">
  109. <li>Full Unicode support in IMP and most apps</li>
  110. <li>Standards-compliant character set handling</li>
  111. <li>39 different translations</li>
  112. </ul>
  113. </div>
  114. <div class="slide">
  115. <h1>Why: The Project</h1>
  116. <ul class="incremental">
  117. <li>Incredibly feature-rich</li>
  118. <li>Built through more than eight years of development ...</li>
  119. <li>... of real-world production web applications</li>
  120. <li>Constantly updated, improved, innovated, and refactored</li>
  121. </ul>
  122. </div>
  123. <!-- Skeleton -->
  124. <div class="slide">
  125. <h1>Building Your Own</h1>
  126. <p><em>In which the intrepid audience gets l33t</em></p>
  127. </div>
  128. <div class="slide">
  129. <h1>Where to start?</h1>
  130. <p class="incremental"><img src="graphics/skeleton.gif" alt="With a skeleton!" /></p>
  131. </div>
  132. <div class="slide">
  133. <h1>Horde Skeleton</h1>
  134. <p><em>Everything you need to write a standard Horde application</em></p>
  135. </div>
  136. <!-- Demo 1: propertyTracker -->
  137. <div class="slide">
  138. <h1>What if you want something like this?</h1>
  139. <p><a target="_blank" href="https://horde.org/papers/nyphpcon-2006-06/" title="Property Tracking Tutorial"><img src="graphics/tracker.png" alt="Property Tracking Tutorial" /></a></p>
  140. </div>
  141. <div class="slide">
  142. <h1>Tools used</h1>
  143. <ul>
  144. <li>RDO</li>
  145. <li>Horde_Form</li>
  146. <li>RDO Helpers</li>
  147. <li><a href="http://www.prototypejs.org/" target="_blank">Prototype</a></li>
  148. <li><a href="http://script.aculo.us/" target="_blank">Scriptaculous</a></li>
  149. <li><a href="http://google.com/apis/maps/" target="_blank">Google Maps</a></li>
  150. <li><a href="http://developer.yahoo.com/maps/rest/V1/geocode.html" target="_blank">Yahoo! Geocoding</a></li>
  151. </ul>
  152. </div>
  153. <div class="slide">
  154. <h1>Why, Continued</h1>
  155. <p><em>PHP 5 and the future of Horde</em></p>
  156. <ul class="incremental">
  157. <li>RDO: lightweight, PDO-based ORM</li>
  158. <li>Automatic generation of Model classes</li>
  159. <li>Override with customized Model</li>
  160. <li>Automatic generation of Horde_Forms from Model</li>
  161. </ul>
  162. </div>
  163. <div class="slide">
  164. <h1>Introducing RDO</h1>
  165. <ul class="incremental">
  166. <li>ORM - Object-Relational Mapping</li>
  167. <li>Uses PDO drivers</li>
  168. <li>Full use of PHP 5 interfaces - Iterator, IteratorAggregate, ArrayAccess, Countable, etc.</li>
  169. </ul>
  170. </div>
  171. <div class="slide">
  172. <h1>RDO Example Usage</h1>
  173. <pre>$um = new UserMapper();
  174. $userCount = $um-&gt;count(); // Count all users.
  175. $exists = $um-&gt;exists(1); // Check if id 1 exists.
  176. // Look for Alice
  177. $user = $um-&gt;find(Horde_RDO::FIND_FIRST,
  178. array('name' => 'Alice'));
  179. if ($user) {
  180. echo "Found Alice: id $user-&gt;id\n";
  181. } else {
  182. // Create a new user.
  183. }
  184. </pre>
  185. </div>
  186. <div class="slide">
  187. <h1>RDO: Creating &amp; Editing</h1>
  188. <pre>
  189. $user = $um-&gt;create(array(
  190. 'name' => 'Alice',
  191. 'phone' => '212-555-6565'));
  192. echo "Created new user with id: {$user-&gt;id}\n";
  193. // Change the name of the user and save.
  194. $user-&gt;name = 'Bob';
  195. $user-&gt;save();
  196. </pre>
  197. </div>
  198. <div class="slide">
  199. <h1>RDO: More Find &amp; Delete</h1>
  200. <pre>
  201. // List all users.
  202. echo "Looking for all:\n";
  203. foreach ($um-&gt;find(Horde_RDO::FIND_ALL) as $user) {
  204. echo " (" . $user-&gt;id
  205. . ") " . $user-&gt;name . "\n";
  206. }
  207. // Fetch id 2 and delete.
  208. $user = $um-&gt;find(2);
  209. $user-&gt;delete();
  210. </pre>
  211. </div>
  212. <div class="slide">
  213. <h1>Form Generation</h1>
  214. <pre>
  215. $vars = Variables::getDefaultVariables();
  216. $form = new Horde_Form_Helper($mapper, $vars,
  217. 'My Form Title');
  218. $form-&gt;renderActive(); // Edit form
  219. $form-&gt;delete(); // process a delete action
  220. $form-&gt;update(); // process an update form
  221. $form-&gt;create(); // process a create form
  222. </pre>
  223. </div>
  224. <!-- Lens slides -->
  225. <div class="slide">
  226. <h1>Horde_RDO_Lens</h1>
  227. <h2>Motivation: How many times do I have to loop through this #*)&%% array?</h2>
  228. <pre>$data = array();
  229. while ($row = mysql_fetch_array()) {
  230. $data[] = $row;
  231. }
  232. foreach ($data as $index => $row) {
  233. $data[$index]['foo'] = format_somehow($row['foo']);
  234. }
  235. foreach ($data as $row) {
  236. echo '&lt;p&gt;' . display($row) . '&lt;/p&gt;';
  237. }
  238. </pre>
  239. </div>
  240. <div class="slide">
  241. <h1>Remember Flyweight?</h1>
  242. <p><a target="_blank" href="http://en.wikipedia.org/wiki/Flyweight_pattern">http://en.wikipedia.org/wiki/Flyweight_pattern</a></p>
  243. <div class="handout">
  244. <p>Flyweight is a software design pattern. When many objects must be
  245. manipulated and these cannot afford to have extraneous data,
  246. flyweight is appropriate.</p>
  247. <p>In the flyweight pattern, the data has no pointers to the data
  248. type methods, because these would consume too much space. Instead,
  249. the subroutines are called directly. In some cases, flyweight
  250. inheritance is performed by &quot;shift-in&quot; and
  251. &quot;shift-out&quot; data markers as a higher-level operation
  252. cycles through an array of flyweight data.</p>
  253. <p>One classic example of a flyweight pattern are the characters
  254. stored in a word processor. Each character represents an object that
  255. has a font face, font size, and other formatting data. As you can
  256. imagine, a large document with this data structure would bloat the
  257. memory footprint of the word processor. Moreover, since much of this
  258. data is repeated, there must be a way to reduce the footprint - the
  259. Flyweight pattern. Each of the character objects would contain a
  260. reference to a separate formatting object which contains the
  261. required properties. This greatly reduces the memory footprint by
  262. combining all of the like-formatted characters into simpler objects
  263. that reference a single formatting object.</p>
  264. </div>
  265. </div>
  266. <div class="slide">
  267. <h1>Lens use</h1>
  268. <pre>
  269. $items = $mapper-&gt;find(Horde_RDO::FIND_ALL);
  270. $formattedItems = new Horde_RDO_Decorating_Iterator(
  271. $items, new Horde_RDO_Lens());
  272. echo '&lt;ul&gt;';
  273. foreach ($formattedItems as $item) {
  274. echo '&lt;li&gt;' . $item-&gt;name
  275. . ' :' . $item-&gt;desc . '&lt;/li&gt;';
  276. }
  277. echo '&lt;/ul&gt;';
  278. </pre>
  279. </div>
  280. <div class="slide">
  281. <h1>Lens Implementation</h1>
  282. <ul class="incremental">
  283. <li>OuterIterator implementation</li>
  284. <li>Lens interface</li>
  285. <li>Base Lens implementation</li>
  286. <li><a target="_blank" href="source.php?file=lens">Code</a></li>
  287. </ul>
  288. </div>
  289. <!-- Demo 2: packages -->
  290. <div class="slide">
  291. <h1>A Package Tracking Application</h1>
  292. <p><img src="graphics/package_tracking_1.png" /></p>
  293. </div>
  294. <div class="slide">
  295. <h1>Package Tracking: Delivery Tracking</h1>
  296. <p><img src="graphics/package_tracking_2.png" /></p>
  297. </div>
  298. <div class="slide">
  299. <h1>Package Tracking Code</h1>
  300. <p><a href="packages.tar.gz">The Code</a></p>
  301. <p>Drop the config/registry.d-packages.php file into your
  302. horde/config/registry.d/ directory with any appropriate changes, and
  303. use with Horde from CVS (3.2-CVS).</p>
  304. </div>
  305. <!-- WebDAV -->
  306. <div class="slide">
  307. <h1>Doing more with our data</h1>
  308. <p>Let's provide a different way to see the packages we're
  309. expecting. How about WebDAV?</p>
  310. </div>
  311. <div class="slide">
  312. <h1>WebDAV browsing made simple</h1>
  313. <p><img src="graphics/webdav.png" /></p>
  314. </div>
  315. <div class="slide">
  316. <h1>Obrowser, where art thou?</h1>
  317. <p>Alternate ways to see what WebDAV sees:</p>
  318. <p><img src="graphics/obrowser_1.png" /></p>
  319. <p><img src="graphics/obrowser_2.png" /></p>
  320. </div>
  321. <div class="slide">
  322. <h1>Implementing /browse</h1>
  323. <ul class="incremental">
  324. <li>Single API method</li>
  325. <li>Takes a path and an optional list of property names</li>
  326. <li>Returns an array depending on the path</li>
  327. <li><a target="_blank" href="source.php?file=browse">Code</a></li>
  328. </ul>
  329. </div>
  330. <!-- External page integration -->
  331. <div class="slide">
  332. <h1>External use of Horde data</h1>
  333. <p><a target="_blank" href="source.php?file=weather"><img src="graphics/weather.png" /></a></p>
  334. </div>
  335. <div class="slide">
  336. <h1>Setup Code</h1>
  337. <dl>
  338. <dt><code>@define('AUTH_HANDLER', true);</code></dt>
  339. <dd>Tell Horde not to throw someone to a login screen; you'll handle authentication.</dd>
  340. <dt><code>$session_control = 'none';</code></dt>
  341. <dd>Don't use sessions</dd>
  342. <dt><code>require_once '/var/www/horde/lib/base.php';</code></dt>
  343. <dd>Load a base Horde environment</dd>
  344. </dl>
  345. </div>
  346. <div class="slide">
  347. <h1>Getting Block Content</h1>
  348. <pre>require_once 'Horde/Block/Collection.php';
  349. $weather = Horde_Block_Collection::getBlock(
  350. 'horde',
  351. 'weatherdotcom',
  352. array('location' =&gt; 'Boston, MA',
  353. 'days' =&gt; 3,
  354. 'units' =&gt; 'standard'));
  355. </pre>
  356. </div>
  357. <div class="slide">
  358. <h1>Showing Block Content</h1>
  359. <pre>echo $weather-&gt;getTitle();
  360. echo $weather-&gt;getContent();</pre>
  361. </div>
  362. <!-- Fin -->
  363. <div class="slide">
  364. <h1>Questions?</h1>
  365. </div>
  366. <div class="slide">
  367. <h1>Resources</h1>
  368. <ul>
  369. <li>The Horde website: <a href="http://www.horde.org/" target="_blank">http://www.horde.org/</a></li>
  370. <li>Developer Documentation: <a href="http://dev.horde.org/" target="_blank">http://dev.horde.org/</a></li>
  371. <li>Wiki: <a href="http://wiki.horde.org/" target="_blank">http://wiki.horde.org/</a></li>
  372. <li>Prototype: <a href="http://www.prototypejs.org/" target="_blank">http://www.prototypejs.org/</a></li>
  373. <li>Scriptaculous: <a href="http://script.aculo.us/" target="_blank">http://script.aculo.us/</a></li>
  374. <li>Google Maps: <a href="http://google.com/apis/maps/" target="_blank">http://google.com/apis/maps/</a></li>
  375. <li>Yahoo! APIs: <a href="http://developer.yahoo.com/maps/rest/V1/geocode.html" target="_blank">http://developer.yahoo.com/maps/rest/V1/geocode.html</a></li>
  376. </ul>
  377. </div>
  378. <!-- End Slides -->
  379. </div>
  380. </body>
  381. </html>