Fork me on GitHub
 

Taken from a developer workshop led by Marc-Andre  


Resources needed: ImpressCMS 1.1; imBlogging module (add links to SVN)


imblogging/class/post.php is where it all starts - Basic principle: The object should have all the information it needs to understand what he is managing and how he is made, so the constructor of a class extending IcmsPersistableObject will initiate "variable" and this is how the object itself will know what are the fields he is managing


IcmsPersistableObject::quickInitVar() is a new method which improves the original XoopsObject::initVar() Second basic principle: When something is always the same 80% of the time, we create a convention and always do this like this except otherwise stipulated. This is "Convention Over Configuration" concept: http://en.wikipedia.org/wiki/Convention_over_Configuration


Using quickInitVar, some parameters of initVar are set by default for you: $options='', $maxlength=null, $multlingual=$false, etc. IPF (IcmsPersistable Framework) will create the object form for us. To do so, it needs to know what is the Caption and the Description of every field, right?


Another example of CoC (Convention Over Configuration) = if you don't specify $form_caption and/or $form_dsc, IPF will try to do it for you! Now, open kernel/IcmsPersistableObject - IcmsPersistableObject::quickInitVar will call IcmsPersistableObject::initVar and look a lines 109-120.


if ($this->handler && (!$form_caption || $form_caption == '')) {
$dyn_form_caption = strtoupper('_CO_' .
$this->handler->_moduleName .
'_' .$this->handler->_itemname . '_' . $key);
if (defined($dyn_form_caption)) {
$form_caption = constant($dyn_form_caption);
}
}
if ($this->handler && (!$form_dsc || $form_dsc == '')) {
$dyn_form_dsc = strtoupper('_CO_' .
$this->handler->_moduleName .
'_' . $this->handler->_itemname . '_' . $key . '_DSC');
if (defined($dyn_form_dsc)) {
$form_dsc = constant($dyn_form_dsc);
}
}

If $form_caption or $form_dsc are false then IPF will check if there is a constant already defined with this pattern: _CO___ So, for example, for the post_title field of ImbloggingPost, you need to have this define _CO_IMBLOGGING_POST_POST_TITLE in the common.php language file. imblogging/language/english/common.php: define("_CO_IMBLOGGING_POST_POST_TITLE", "Title"); Same thing for the field's description: _CO____DSC. So, define("_CO_IMBLOGGING_POST_POST_TITLE_DSC", ""); Back to post.php $this->quickInitVar('post_status', XOBJ_DTYPE_INT, false, false, false, IMBLOGGING_POST_STATUS_PUBLISHED); This line is has little bit more parameter, because I needed to set a default value for this field the 6th parameter, IMBLOGGING_POST_STATUS_PUBLISHED. The default value of a field is used at many places:



  1. When the object is created, the field will have this default value, until it gets loaded with the database values (if it's an existing object)

  2. Because of that, when you call the new object form, the control will have this default value in the form. In this example, when creating a new Post, the Status field will have the value IMBLOGGING_POST_STATUS_PUBLISHED, which is 1, which will be translated into "Published"

  3. The default value will also be used when dynamically creating the table when updating the module


In this example, when creating the table the script will add "default = 1" to the post_status field when defining the table structure post_comments is a field where we track the number of comments a post has, however, we don't want this field to be displayed on the create or edit form, so, in post.php, $this->hideFieldFromForm('post_comments'); This will turn the displayOnForm attribute of this field to False and it will not be displayed on the form. Doing this, we are setting the default behavior, but when actually calling the form to be created, we could make this field display if we want by simply: $postObj->showFieldOnForm('post_comment'); IcmsPersistableObject::hideFieldFromForm and IcmsPersistableObject::showFieldFromForm can have string or array as parameter If array, multiple fields will be changed at once : $postObj->showFieldOnForm(array('post_comment', 'post_published_date', 'post_status'); $this->initCommonVar('counter', false); IcmsPersistableObject::initCommonVar() : again, CoC: when something is used 80% of the time, make convention ! using initCommonVar, you can quickly initiate a few variables which we are using quite often. So far, you can use this to initiate:dohtml, dobr, doimage, dosmiley, doxcode, meta_keywords, meta_description, short_url, hierarchy_path, counter, weight, custom_css So, these are all fields you can easily initiate on your object, using initCommonVar. And, yes, they are part of the object. when the database gets created or updated ()when module is updated), if IcmsDatabaseUpdater sees for example, the counter common field, it will add a counter field in your table


initCommonVar('counter'), 

is the exact same thing as if you did:


$this->initVar('counter', XOBJ_DTYPE_INT,$value, false, null, '', false, 
_CO_ICMS_COUNTER_FORM_CAPTION, '', false, true, $true);

but you see that using initCommonVar is far less code! In post.php -


$this->setControl('post_content', 'dhtmltextarea');

by default, if you don't specify a control, IPF will create a default one for you example:


$this->quickInitVar('post_title', XOBJ_DTYPE_TXTBOX);

will create a simple textbox size 50 maxlength 255


$this->quickInitVar('post_content', XOBJ_DTYPE_TXTAREA);

will create a simple textarea (textsarea)


$this->quickInitVar('post_published_date', XOBJ_DTYPE_LTIME);

will create a datetime picker the control that is created is decided based on the field type



  • XOBJ_DTYPE_INT = textbox, size 10 i think

  • XOBJ_DTYPE_TXTBOX = text box size 50

  • XOBJ_DTYPE_TXTAREA = simple text area

  • XOBJ_DTYPE_LTIME = datetime picker


now, if you want to customize the control for a field, this is where you use IcmsPersistableObject::setControl For example, for the field post_content: i want to use the default text editor of the site, so I do:


$this->setControl('post_content', 'dhtmltextarea');

post_uid: I want a selectbox with users


$this->setControl('post_uid', 'user');

post_cancomment: I want a yes no radio


$this->setControl('post_cancomment', 'yesno');

so far, here are the second parameter you can use with setControl:



  • check

  • color

  • radio

  • label

  • textarea

  • dhtmltextarea

  • theme

  • theme_multi

  • timezone

  • group

  • group_multi

  • user_multi

  • password

  • country

  • urllink

  • richfile


all the form field types, and many others, which are defined in class/icmsform/elements/. And, you can create your own. Let's say you want to create a Birthday control - all you have to do is to create a file here: yourmodule/class/form/elements/yourmodulebirthdayelement.php. And then:


this->setControl('your_field_name', 'birthday')

Continuing in post.php -


$this->setControl('post_status', array(
'itemHandler' => 'post',
'method' => 'getPost_statusArray',
'module' => 'imblogging'));

You can use setControl with a second parameter as an array - in this case, post_status will be a selectbox, and the options i it will be the result of the call on the method ImbloggingPostHandler::getPost_statusArray()


 

Last modified on 2010/11/28 by Anonymous
Comments
The comments are owned by the poster. We aren't responsible for their content.