Skip to content

Move your article’s data header to footer

After very busy work time I can write some other articles that I hope you find interesting.
I am involved in a large project for a news portal http://www.arezzonotizie.it/.
For this project I made some patches and writed some code personalization.
The first plugin I want to present is a mambot to move data from header to footer.
The standard joomla article's header show some elements in the header of the article:

  • pdf icon
  • print icon
  • e-mail icon
  • date created
  • author name

The mambot I have developed move all of this elements in the footer of the article.
As a bonus if the author have a linked contact, shows hyperlink to the correspondig author contact page.

PHP:
  1. /**
  2. * Authors Link Bot
  3. * @version 1.0
  4. * @package None
  5. * @copyright (C) Copyright 2007-2007 by Marco Sbragi
  6. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL
  7. */
  8.  
  9. defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
  10. $_MAMBOTS->registerFunction( 'onPrepareContent', 'botMosAuthorLink' );
  11.  
  12. function botMosAuthorLink( $published, &$row, &$params, $page=0  ) {
  13.     global $mosConfig_absolute_path, $database;
  14.  
  15.     $showbottom = true;
  16.  
  17.     // $row->created_by       -> Id dell'autore
  18.     // $row->created_by_alias -> Alias autore
  19.     // $row->Author           -> Nome Autore
  20.    
  21.     if($_REQUEST['task'] != 'view') { return true; }
  22.     if(! $published)                { return true; }
  23.     if($params->get( 'popup' ) )    { return true; }
  24.  
  25.    
  26.     if((@$row->created_by) && (! $my->id)) {
  27.         if((!$row->created_by_alias) || (strtolower(($row->created_by_alias) == strtolower($row->author)))) {
  28.             // Check If declared on Contacts
  29.             $database->setQuery( "SELECT id FROM #__menu WHERE link = 'index.php?option=com_contact' AND published=1" );
  30.             $Itemid = (int) $database->loadResult();
  31.  
  32.             $query = "SELECT id"
  33.                 . "\n FROM #__contact_details"
  34.                 . "\n WHERE user_id = {$row->created_by}"
  35.                 . "\n AND published = 1"
  36.                 . "\n LIMIT 1";
  37.  
  38.             $database->setQuery( $query );
  39.             $Id = (int) $database->loadResult();
  40.             if($Id) {
  41.                 $author_link = sefRelToAbs("index.php?option=com_contact&task=view&contact_id={$Id}&Itemid={$Itemid}");
  42.                 $row->created_by_alias = "<a href='" . $author_link . "'>" . $row->author . "</a>";
  43.             } else {
  44.                 $row->created_by_alias = $row->author;
  45.             }
  46.         }
  47.  
  48.         // Use standard jOOmla format
  49.         if(! $showbottom) {
  50.             return true;
  51.         }
  52.  
  53.         $showEmail = $params->get('email');
  54.         $showPrint = $params->get('print');
  55.         $showPdf   = $params->get('pdf');
  56.  
  57.         $params->set('author',0);
  58.         $params->set('createdate',0);
  59.         $params->set('print',0);
  60.         $params->set('email',0);
  61.         $params->set('pdf',0);
  62.  
  63.         $print_link = $mosConfig_live_site. '/index2.php?option=com_content&amp;task=view&amp;id=' . $row->id .'&amp;pop=1&amp;page='. $page . $row->Itemid_link;
  64.  
  65.         $str_html  = '<table style="clear: both;" width="100%" class="botAuthor" cellspacing="0" cellpadding="0">';
  66.         $str_html .= '<tr>';
  67.         $str_html .= '<td align="left">' . strtoupper(mosFormatDate($row->created)) . ' - ' . $row->created_by_alias . '</td>';
  68.         // $showPdf   && $str_html .= botMosAuthor_PdfIcon($row, $params );
  69.         $showPrint && $str_html .= botMosAuthor_PrintIcon($row, $params, $print_link );
  70.         $showEmail && $str_html .= botMosAuthor_EmailIcon($row, $params);
  71.         $str_html .= '</tr>';
  72.         $str_html .= '</table>';
  73.         $row->text .= $str_html;
  74.     }
  75.  
  76.     return true;
  77. }
  78.  
  79. function botMosAuthor_PdfIcon( &$row, &$params ) {
  80.     global $mosConfig_live_site, $Itemid, $task;
  81.        
  82.     if ( $params->get( 'popup' ) ) {
  83.         return '';
  84.     }
  85.  
  86.     $status = 'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,width=640,height=480,directories=no,location=no';
  87.     $link = $mosConfig_live_site. '/index2.php?option=com_content&amp;do_pdf=1&amp;id='. $row->id;
  88.        
  89.     if ( $params->get( 'icons' ) ) {
  90.         $image = mosAdminMenus::ImageCheck( 'pdf_button.png', '/images/M_images/', NULL, NULL, _CMN_PDF, _CMN_PDF );
  91.     } else {
  92.         $image = '&nbsp;'. _CMN_PDF;
  93.     }
  94.     $str_html  = '<td align="right" width="16" class="buttonheading">';
  95.     $str_html .= '<a href="' . $link .'" target="_blank" onclick="window.open(\'' . $link .'\',\'win2\',\'' . $status. '\'); return false;" title="' . _CMN_PDF .'">' . $image . '</a>';
  96.     $str_html .= '</td>';
  97.     return $str_html;
  98. }
  99.  
  100. function botMosAuthor_EmailIcon( &$row, &$params ) {
  101.     global $mosConfig_live_site, $Itemid, $task;
  102.        
  103.     if ( $params->get( 'popup' ) ) {
  104.         return '';
  105.     }
  106.  
  107.     $status = 'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,width=400,height=250,directories=no,location=no';
  108.        
  109.     $_Itemid = '&amp;itemid='. $Itemid;
  110.        
  111.     $link   = $mosConfig_live_site .'/index2.php?option=com_content&amp;task=emailform&amp;id='. $row->id . $_Itemid;
  112.        
  113.     if ( $params->get( 'icons' ) ) {
  114.         $image = mosAdminMenus::ImageCheck( 'emailButton.png', '/images/M_images/', NULL, NULL, _CMN_EMAIL, _CMN_EMAIL );
  115.     } else {
  116.         $image = '&nbsp;'. _CMN_EMAIL;
  117.     }
  118.     $str_html  = '<td align="right" width="16" class="buttonheading">';
  119.     $str_html .= '<a href="' . $link .'" target="_blank" onclick="window.open(\'' . $link .'\',\'win2\',\'' . $status. '\'); return false;" title="' . _CMN_EMAIL .'">' . $image . '</a>';
  120.     $str_html .= '</td>';
  121.     return $str_html;
  122. }
  123.  
  124. function botMosAuthor_PrintIcon( &$row, &$params, $link ) {
  125.     global $mosConfig_live_site, $Itemid, $task;
  126.        
  127.     $status = 'status=no,toolbar=no,scrollbars=yes,titlebar=no,menubar=no,resizable=yes,width=640,height=480,directories=no,location=no';
  128.        
  129.     $_Itemid = '&amp;itemid='. $Itemid;
  130.        
  131.     if ( $params->get( 'icons' ) ) {
  132.         $image = mosAdminMenus::ImageCheck( 'printButton.png', '/images/M_images/', NULL, NULL, _CMN_PRINT, _CMN_PRINT );
  133.     } else {
  134.         $image = _ICON_SEP .'&nbsp;'. _CMN_PRINT. '&nbsp;'. _ICON_SEP;
  135.     }
  136.  
  137.     $str_html  = '<td align="right" width="16" class="buttonheading">';
  138.     if ( $params->get( 'popup' ) ) {
  139.         $str_html .= '<a href="#" onclick="javascript:window.print(); return false;" title="' . _CMN_PRINT . '">' . $image . '</a>';
  140.     } else {
  141.         $str_html .= '<a href="' . $link .'" target="_blank" onclick="window.open(\'' . $link .'\',\'win2\',\'' . $status. '\'); return false;" title="' . _CMN_PRINT .'">' . $image . '</a>';
  142.     }
  143.     $str_html .= '</td>';
  144.     return $str_html;
  145. }

For anyone of you interested in how to write mambot for jOOmla read this article on jOOmla help site http://help.joomla.org/content/category/12/113/125

Download mambot

If you wish to use the mambot as a simple author to contact link and want to leave the standard jOOmla layout you must change the declaration at line 15 from

PHP:
  1. // $showbottom = true;
  2. // To
  3. $showbottom = false;

Want a free layout for your cake?

If you want a layout for your new cake app and don't want to waste your time you can benefit of thousands of templates made for jOOmla.
The translation from joomla templates to cake layout is a very very simple job.

Let me explain from start:
A jOOmla template is composed of this main files and dirs

index.php - main template file
css/template_css.css - stylesheet file
images/* - all the images needed from stylesheet and main file

this can vary but this is the minimum requirements.

The first thing to do is to move the css/* files in your webroot/css
then move the images dir in your webroot.

webroot
|----css
|       template_css.css
|       cake.generic.css
|
|----img/*
|
|----images/*

If you wish to have only one dir for all your images then you must change all reference to images/ with img/ in your index.php and template_css.css

Now move your index.php file to your cakeroot/views/layout and rename it to default.thtml

Ok this is the 50% of job :).

Now we must modify the default.thtml file to meet cake requirements.

This a simple joomla template 2 (columns i used for one of my clients)
You can view how it renders here

CODE:
  1. <?php
  2. defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
  3. ob_start("accSub_ob_callback");
  4. // needed to seperate the ISO number from the language file constant _ISO
  5. $iso = split( '=', _ISO );
  6. // Master paths:
  7. $path     = $mosConfig_live_site .'/templates/dara';
  8. $path_images    = $path .'/images';
  9. ?>
  10. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  11. <html xmlns="http://www.w3.org/1999/xhtml">
  12. <head>
  13. <?php
  14. if ( $my->id ) {
  15.     initEditor();
  16. }
  17. ?>
  18. <meta http-equiv="Content-Type" content="text/html; _ISO" />
  19. <?php mosShowHead(); ?>
  20. <link rel="shortcut icon" href="/images/favicon.ico" />
  21. </link><link rel="stylesheet" type="text/css" href="/css/template_css.css" />
  22. <!--[if lt IE 7]>
  23.     </link><link rel="stylesheet" type="text/css" href="/css/template_css_ie.css" />
  24. <![endif]-->
  25. </link></meta></head>
  26. <body  id="home">
  27.  
  28. <div id="site">
  29.     <div id="shadow">
  30.         <div id="wrapper">
  31.             <div id="masthead">
  32.                 <h1><?php echo $mosConfig_sitename; ?></h1>
  33.                 <!--<a href="#" title="Click here to sign up now." id="signUpNow">Sign up now!-->
  34.             </div>
  35.  
  36.             <div id="mainMenu">
  37.                 <?php mosLoadModules ( 'header', -2 ); ?>
  38.                 <br class="clearing" />
  39.             </div>
  40.  
  41.             <div id="content">
  42.                 <?php if($option == 'com_frontpage' || $option == '') { ?>
  43.                 <div id="homead">
  44.                     <?php mosLoadModules ( 'banner', -2 ); ?>
  45.                 </div>
  46.                 <?php } ?>
  47.                 <div id="subMenu"><?php mosLoadModules ( 'left', -2 ); ?></div>
  48.                 <div id="main"><?php mosMainBody(); ?></div>
  49.                 <br class="clearing" />
  50.             </div>
  51.  
  52.             <div id="footer">
  53.               <a taget="_blank" href="http://www.joomla.org/">jOOmla cms</a>
  54.               &nbsp;|&nbsp;Powered by <a taget="_blank" href="http://www.nospace.net/">nospace</a>
  55.               &nbsp;|&nbsp;&copy; italplan 2006
  56.             </div>
  57.         </div>
  58.     </div>
  59. </div>
  60. <map name="HomeMap">
  61. <area href="index.php?lang=it" shape="polygon" coords="138, 76, 324, 76, 361, 38, 183, 37">
  62. </area><area href="index.php?lang=en" shape="polygon" coords="142, 130, 327, 129, 359, 93, 186, 93">
  63. </area><area href="index.php?lang=pt" shape="polygon" coords="141, 184, 330, 184, 364, 148, 187, 147">
  64. <!--
  65. <area href="index.php?lang=es" shape="polygon" coords="142, 239, 328, 239, 365, 202, 186, 202">
  66. -->
  67. </area></map>
  68. </body>
  69. </html>
  70. <?php ob_end_flush(); ?>

The translation is very simple:
Replace mosMainBody(); jOOmla functions with echo content_for_layout;
And if needed replace the mosLoadModules() functions with renderElements()

Here the revised template for cake:

CODE:
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <!-- cakePHP header Begin -->
  5. <title>CakePHP(tm) : <?php echo $title_for_layout;?></title>
  6. <link rel="icon" href="favicon.ico" type="image/x-icon" />
  7. </link><link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
  8. <?php
  9.   echo $html->css('template_css');
  10.   echo $html->css('cake.generic');
  11.   if(isset($javascript)) {
  12.     echo $javascript->link('jquery-latest.js') . "\n";
  13.   }
  14.   echo isset($head) ? $head->registered() : '';
  15.   echo "\n";
  16. ?>
  17. <!-- cakePHP header End -->
  18. </link></head>
  19. <body id="home">
  20. <div id="site">
  21.     <div id="shadow">
  22.         <div id="wrapper">
  23.             <div id="masthead">
  24.             </div>
  25.             <div id="mainMenu">
  26.                 <!-- cakePHP Top Menu -->
  27.                 <?php echo $this->renderElement('menus/topMenu'); ?>
  28.                 <br class="clearing" />
  29.             </div>
  30.             <div id="content">
  31.                 <div id="homead">
  32.                     <?php echo $this->renderElement('banner'); ?>
  33.                 </div>
  34.                 <div id="subMenu">
  35.                     <!-- cakePHP left Menu -->
  36.                     <?php echo $this->renderElement('menus/leftMenu'); ?>
  37.                 </div>
  38.                 <div id="main">
  39.                     <!-- cakePHP contents -->
  40.                     <?php $session->flash(); ?>
  41.                     <?php echo $content_for_layout; ?>
  42.                 </div>
  43.                 <br class="clearing" />
  44.             </div>
  45.             <div id="footer">
  46.               <a taget="_blank" href="http://www.joomla.org/">jOOmla cms</a>
  47.                | Powered by <a taget="_blank" href="http://www.nospace.net/">nospace</a>
  48.                | and <a taget="_blank" href="http://www.cakephp.org/">cakephp</a>
  49.             </div>
  50.         </div>
  51.     </div>
  52. </div>
  53. </body>
  54. </html>

if you want tons of free templates go to jOOmla forum it is a very good resource also for making templates that render the same on different browser

Bypass jOOmla acl for automatic publishing

You knows that with jOOmla only publishers can publish there are situations with small groups I had requests for lowering the acl and permits to publish their articles also for authors. This is a very simple trick to do.

Locate these lines near the top of components/com_content/content.php

PHP:
  1. // Editor usertype check
  2. $access = new stdClass();
  3. $access->canEdit    = $acl->acl_check( 'action', 'edit', 'users', $my->usertype, 'content', 'all' );
  4. $access->canEditOwn = $acl->acl_check( 'action', 'edit', 'users', $my->usertype, 'content', 'own' );
  5. $access->canPublish = $acl->acl_check( 'action', 'publish', 'users', $my->usertype, 'content', 'all' );

And replace with:

PHP:
  1. // Editor usertype check
  2. $access = new stdClass();
  3. // ---------------------------------------------------------------------------
  4. // Marco 05.12.2005
  5. // Show publish in frontend even for authors
  6. // http://blog.nospace.net/
  7. // ---------------------------------------------------------------------------
  8. $acl->_mos_add_acl( 'action', 'publish', 'users', 'editor', 'content', 'all' );
  9. $acl->_mos_add_acl( 'action', 'publish', 'users', 'author', 'content', 'all' );
  10. // ---------------------------------------------------------------------------
  11. $access->canEdit    = $acl->acl_check( 'action', 'edit', 'users', $my->usertype, 'content', 'all' );
  12. $access->canEditOwn = $acl->acl_check( 'action', 'edit', 'users', $my->usertype, 'content', 'own' );
  13. $access->canPublish = $acl->acl_check( 'action', 'publish', 'users', $my->usertype, 'content', 'all' );

And then locate this lines:

PHP:
  1. } else {
  2.         $row->sectionid = $sectionid;
  3.         $row->version = 0;
  4.         $row->state = 0; // <<<<----------- replace 0 with 1 if you wish publish checkbox auto checked
  5.         $row->ordering = 0;
  6.         $row->images = array();
  7.         $row->publish_up = date( 'Y-m-d', time() );
  8.         $row->publish_down = 'Mai';
  9.         $row->creator = 0;
  10.         $row->modifier = 0;
  11.         $row->frontpage = 0;
  12.     }

that's all.

When model::getLastInsertId() is not enough.

There are situation where the very useful model::getLastInsertId() function is not enough.
For example if you are editing a records of an hasMany parts and you want to return to the list of records that belongsTo its parent.

Let me explain better:

PHP:
  1. /*
  2. ** Post model
  3. ** File: models/post.php
  4. */
  5. class Post extends AppModel {
  6.     var $name = 'Post';
  7.     var $hasMany = array('Comment');
  8. }

PHP:
  1. /*
  2. ** Comment model
  3. ** File: models/comment.php
  4. */
  5. class Comment extends AppModel {
  6.     var $name = 'Comment';
  7.     var $belongsTo = array('Post');
  8. }

When you display a post with its comments you have something like this:

Post #id: 1234
Well this is my first post

Comments:
#1 Good
#2 Very good

What if you want to add a comment to this post and then return to this list?
You must save your post.id and put it in the comment.post_id field and then redisplay the post and the list of relateds comments.

This is the extension for AppModel:

PHP:
  1. /*
  2. ** AppModel model
  3. ** File: /app_model.php
  4. */
  5. class AppModel extends Model {
  6.  
  7.     function setLastUsedId( $id=null ) {
  8.         // Store Id in session var
  9.         $_SESSION['cacheId'][$this->name] = $id;
  10.     }
  11.  
  12.     function getLastUsedId() {
  13.         // Retrieve Id from session var
  14.         $ret = @$_SESSION['cacheId'][$this->name];
  15.         return $ret;
  16.     }
  17.  
  18.     function afterFind( $result ) {
  19.         // Save id after succesful model::find or model::read
  20.         if($this->id) {
  21.             $this->setLastUsedId( $this->id );
  22.         }
  23.         return parent::afterFind( $result );
  24.     }
  25.  
  26.     function afterSave() {
  27.         if(!$this->id) {
  28.             // This is an add
  29.             $this->setLastUsedId( $this->getLastInsertId() );
  30.         } else {
  31.             // This is an update
  32.             $this->setLastUsedId( $this->id );
  33.         }
  34.         return parent::afterSave();
  35.     }
  36.  
  37.     function beforeDelete() {
  38.         $this->setLastUsedId( $this->id );
  39.         return parent::beforeDelete();
  40.     }
  41.  
  42.     function afterDelete() {
  43.         $this->setLastUsedId( $id = null );
  44.         return parent::afterDelete();
  45.     }
  46.  
  47. }

After this modifications we can use model::getLastUsedId() as for example:

PHP:
  1. /*
  2. ** CommentsController controller
  3. ** File: controllers/comments_controller.php
  4. */
  5. class CommentsController extends AppController {
  6.     var $ name = "Comments";
  7.  
  8.     function index() {
  9.         // we don't want to show a list of all comments
  10.         // but only those related with own's post
  11.         $this->redirect('/posts/view/' . $this->Comment->Post->getLastUsedId() );
  12.         exit();
  13.     }
  14.  
  15.     function add() {
  16.         $post_id = $this->Comment->Post->getLastUsedId();
  17.         if($this->data) {
  18.             $this->data['Comment']['post_id'] = $post_id;
  19.             if( $this->Comment->save( $this->data ) ) {
  20.                 $this->index();
  21.                 return;
  22.             }
  23.         }
  24.         $this->set('post', $this->Comment->Post->read(null, $post_id ); // if you want to show some information of post you are adding  comment
  25.     }
  26.  
  27. }

Obviously this is only an example on how to use this tip.
Excuse me for typos and feel free to comment.

Bar code printing with cake

These days my collegue Leonello and i had the necessity to print barcode label to stick on printed document for the documents management system we have developed in cakephp.
After googling have found this nice library:

http://chir.ag/tech/download/pdfb/

Some testing in pure php and decided that it's a cool system to use.

The integration in cakephp follows these steps:

  1. From above page download PDFB Library - Compact Version - 136kb (For Production Use)
  2. Extract all files in {Cakeroot}/vendors or {App}/vendors (See figure)
  3. Edit line 10 in file pdfb.php
    PHP:
    1. <?php
    2. /*
    3. +-----------------------------------------------------------------+
    4. |   Created by Chirag Mehta - http://chir.ag/tech/download/pdfb   |
    5. |-----------------------------------------------------------------|
    6. |                      For PDFB Library                           |
    7. +-----------------------------------------------------------------+
    8. */
    9.  
    10.   define('FPDF_FONTPATH','font/');

Your pdfb library is now working if you want you can test it so:
Create a controller to make a quick test

PHP:
  1. <?php
  2. /*
  3. ** File:     test_pdfb_controller.php
  4. ** Purpouse: test pdf barcode library
  5. */
  6. class TestPdfbController extends AppController {
  7.     var $name = 'TestPdfb';
  8.     var $uses = array(); // no models needed
  9.  
  10.     function barcode() {
  11.         vendor('pdfb/pdfb');
  12.  
  13.         $this->autoRender = false;
  14.  
  15.         $pdf = new PDFB('P', 'mm', array( 75.0, 33.0 ));
  16.         $pdf->SetMargins(0.0, 0.0);
  17.         $pdf->SetFont("Helvetica", "", 9.5);
  18.  
  19.         $pdf->AddPage();
  20.  
  21.         $doc_id = '1234567';
  22.         $pdf->BarCode($doc_id, "C39", 0, 4, 75.0, 33.0, 1, 1, 1, 1, "", "PNG");
  23.  
  24.         $pdf->SetXY(2, 4);
  25.         $pdf->Cell(0, 0, "Code: 39 - 17 march 2007", 0, 0, 'C');
  26.  
  27.         $pdf->Rect(0.3, 0.3, 74.4, 32.4);
  28.  
  29.         $pdf->SetDisplayMode('real');
  30.         $pdf->Output();
  31.         $pdf->closeParsers();
  32.     }
  33. }
  34.     // BarCode function parameters explanation
  35.     // function BarCode($barcode, $type, $x, $y, $w, $h, $sx, $sy, $xres, $font, $link, $format)
  36.     // $barcode = any alphanumber string or UPC-A valid numeric code
  37.     // $type = one of "C39", "C128A", "C128B", "C128C", "I25", "UPCA"
  38.     // $x, $y = position on the PDF page
  39.     // $w, $h = dimensions of the BarCode image
  40.     // $sx, $sy = X & Y scaling of the BarCode image
  41.     // $xres = thickness of the Bars in the Barcode - X-Resolution (1,2,3)
  42.     // $font = Font size for BarCode value (1,2,3,4,5)
  43.     // $link = URL to link the BarCode to
  44.     // $format = "PNG" (default) or "JPEG"
  45.  
  46.     // If you wish to make high-resolution barcodes:
  47.     // -> use $xres = 2 or $xres = 3
  48.     // -> use $font = 5
  49.     // -> use $w, $h = large dimensions
  50.     // -> use $sx, $sy = (0.5, 0.5) or (0.25, 0.25) to scale it down to desire size.
  51.     // Then zooming into the image you will see that it's quite scalable and high-resolution
  52.  
  53. ?>

For explanation of standard pdf library functions go here

But we can make things better:

First of all create an helper object

PHP:
  1. <?php
  2. /*
  3. ** File: pdf.php
  4. ** Loaction: views/helpers
  5. * help for pdf and barcode printing
  6. * ---------------------------------
  7. * @package helpers
  8. */
  9. vendor('pdfb/pdfb');
  10. class pdfHelper extends PDFB {
  11.     var $headerData = null;
  12.     var $footerData = null;
  13.  
  14.     function __construct($orientation='P', $unit='mm', $format='A4') {
  15.         $this->set($orientation, $unit, $format);
  16.     }
  17.  
  18.     function set($orientation='P', $unit='mm', $format='A4') {
  19.         parent::PDFB($orientation, $unit, $format);
  20.     }
  21.  
  22.     function Header() {
  23.       // To do: manage headerData array
  24.     }
  25.  
  26.     function Footer() {
  27.       // To do: manage footerData array
  28.     }
  29.  
  30. }
  31. ?>

Now create a layout for printing pdf

PHP:
  1. <?php
  2. /*
  3. ** File: pdf.thtml
  4. ** Location: views/layouts
  5. ** Set content-type for pdf printing
  6. */
  7. header("Content-type: application/pdf");
  8. echo $content_for_layout;
  9. ?>

Now create the view

PHP:
  1. <?php
  2. /*
  3. ** File: barcode.thtml
  4. ** Location: views/test_pdfb
  5. */
  6.     $pdf->set('P', 'mm', array( 75.0, 33.0 ));
  7.     $pdf->SetMargins(0.0, 0.0);
  8.     $pdf->SetFont("Helvetica", "", 9.5);
  9.  
  10.     $pdf->AddPage();
  11.  
  12.     //$doc_id = '1234567'; // come from controller
  13.     $pdf->BarCode($doc_id, "C39", 0, 4, 75.0, 33.0, 1, 1, 1, 1, "", "PNG");
  14.  
  15.     $pdf->SetXY(2, 4);
  16.     $pdf->Cell(0, 0, "Code: 39 - 17 march 2007", 0, 0, 'C');
  17.  
  18.     $pdf->Rect(0.3, 0.3, 74.4, 32.4);
  19.  
  20.     $pdf->SetDisplayMode('real');
  21.     $pdf->Output();
  22.     $pdf->closeParsers();
  23. ?>

And finally modify your controller to reflect all changes

PHP:
  1. <?php
  2. /*
  3. ** File:     test_pdfb_controller.php
  4. ** Location: /controllers
  5. ** Purpouse: test pdf barcode library
  6. */
  7. class TestPdfbController extends AppController {
  8.     var $name    = 'TestPdfb';
  9.     var $uses    = array();       // no models needed
  10.     var $helpers = array('pdf')// Use the helper just created
  11.  
  12.     function barcode() {
  13.         $this->layout = 'pdf';           // Set layout to pdf
  14.         $this->set('doc_id', '1234567'); // Set number to print
  15.         $this->render('barcode');
  16.     }
  17. }
  18. ?>

pdfb_barcode.gif
Thats all folks :)

Vim WorkBench

After 15 years I have rediscovered the power of Vi www.vim.org I have used it for long time then I start using M$ Ide's like VB, Visual Studio etc. But now that I am using open source software, I reuse vi for windows for all my work of editing source code. There are a pletora of plugins on the main site vim.org, but i have not found a Project Manager with decent gui interface for windows. For this reason I have decided to write my own. It was developed with VB6. If you want you can download it and give a try.

Vim_WB_1.jpg

Download Vim-WB Setup

The application is supplied as is.
Downloading the application you are conscious to install and use it at your own risk.
I have tested the application but cannot in any manner guarantee that it will work in your configuration.
The application is tested under windows Xp.

before installation
Make sure you have installed VIm 7.0 for windows with ole support
If not download vim from www.vim.org

Installation:
Unzip the file and run VimWBSetup.exe

Run the application

YACCA Yet Another Cake Component for Auth

When I have finished my first application I had the necessity to create an authorization system to control user access.
I have looked around and founded some very good system especially in the bakery repository.
But in my mind I was thinking at something very simple for management.
My idea was to have an approach by rules. A list of ordered rules with allow/deny actions.
Cake Auth Rules
As you can see it is very intuitive how the system works:

  • The first rule allow all
  • The second rule deny access to all actions of controllers that start with Cake
  • The third rule allow access to Controller CakeLogin (All Actions)
  • The fourth allow only the action changepwd of controller CakeUsers
  • And last rule allow access to welcome page.

Continue reading ›

Let’s start

Are you ready?
Any rock concert when I was 18 years old was starting so.
After some attempts hope this is the right one.
For first I have chosen some tools.

  1. The blogger WordPress from http://www.wordpress.org
  2. One minimalist theme barthelme from plaintext.org (I like simplicity)
  3. Some plugins:

And now I hope have time for writing.

Hello Cake world

This is in fact an excuse to write an article with some code snippets in it, just to see how it looks. This is based on the original tutorial that you can find at cakephp wiki

As you know we need to start our MVC project.

We create hello.php for the Model, hello_controller.php for the Controller and an index.thtml as View.

PHP:
  1. <?php
  2. /*
  3. ** hello.php
  4. ** Put this file in your {Cakeinst}/app/model folder
  5. */
  6.  
  7. class Hello extends AppModel { 
  8.   var $name     = 'Hello';
  9.   var $useTable = false;
  10. }
  11. ?>

PHP:
  1. <?php
  2. /*
  3. ** hello_controller.php
  4. ** Put this file in your {Cakeinst}/app/controller folder
  5. */
  6.  
  7. class HelloController extends AppController {
  8.   var $name = "Hello";
  9.   var $uses = 'Hello';
  10.  
  11.   function index() {
  12.     $data = 'Hello world!';
  13.     $this->set('data', $data);
  14.   }
  15.  
  16. }
  17. ?>

PHP:
  1. <!--
  2. /*
  3. ** index.thtml
  4. ** put this file in your {Cakeinst}/app/views/hello folder
  5. */
  6. -->
  7. <hr size=1/>
  8. <h1><?php echo $data ?></h1>
  9. <hr size=1/>

Because we really does not use any database table we may not create the hello.php file (no table no model), but need to inform the controller that we have no model. This is revised version of hello_controller.php.

PHP:
  1. <?php
  2. /*
  3. ** hello_controller.php (revised)
  4. ** Put this file in your {Cakeinst}/app/controller folder
  5. */
  6.  
  7. class HelloController extends AppController {
  8.   var $name = "Hello";
  9.   var $uses = null;
  10.  
  11.   function index() {
  12.     $data = 'Hello world!';
  13.     $this->set('data', $data);
  14.   }
  15.  
  16. }
  17. ?>

Every time you need to use a controller not binded to any database table simply put the statement
var $uses = null;