Chapter 7: Adding Extra Fields [Adding Read and Update functionality for your extra field]
So for our mycck component, we have to create an ARKContexts class as we did for the Item type. In our case, the class will be called ARKContextsMyCCKTextarea.
Therefore, we will add another file in the contexts folder of our package and name it ‘textarea.php.’ The name of the file will have to match the name of the extra field you are adding for inline editing support.
Now, once we have done that, we will create ARKContextsMyCCKTextarea as follows:
class ARKContextsMyCCKTextarea extends ARKContextsBase
{
}
Okay, now, let us look at the constructor first.
public function __construct($id)
{
JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_mycck/tables');
list($item_id,$id) = explode('_',$id);
$this->table = JTable::getInstance('fields','MyCCK');
$this->table->load($id);
$this->table->item_id = $item_id;
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('value')
->from('#__mycck_fields_item')
->where('field_id = '.(int)$id)
->where('item_id = '.(int)$item_id);
$db->setQuery($query);
$value = $db->loadResult();
$this->table->text = $value;
$this->table->title = '';
$this->item = JTable::getInstance('items','MyCCK');
$this->item->load($item_id);
parent::__construct($id);
}
The ID that is passed into the constructor contains both the field type id and the associated item id. We need both of these references, so that we can retrieve the field value in the link table.
You will probably have a similar setup if you are dealing with a Content Construction Kit, so you will have to do something similar to what we have done here.
Now, let us look at the get method:
public function get()
{
if($this->id == null)
return parent::get();
$this->table->articletext = $this->table->text;
return parent::get();
}
Pretty much, standard stuff here. In this method, we set the 'articletext' property to the field's current value as we did for our other types.
Again, in the triggerContentPlugins, method the code implementation is similar to what we did for the Item main type.
public function triggerContentPlugins($rawText)
{
$item = new stdclass;
$item->text = '';
if(isset($rawText))
{
$item->text = $rawText;
$item->file_id = $this->id;
$item->item_id = $this->item_id;
$params = new JObject;
$params->set('inline',false); //set this so that we don't trigger the inline content plugins
$dispatcher = JEventDispatcher::getInstance();
JPluginHelper::importPlugin('content');
$dispatcher->trigger('onContentPrepare', array ('com_mycck.textarea', &$item, &$params, 0));
}
return array( 'data'=>$item->text);
}
The main difference, you will find, is in the save method, this is because we have to manually save the updated text because we are using a link table. Also, this is the same regarding versioning, because of the use of a link table to store the textarea’s text content.
public function save($data,$type = 'body')
{
if($this->id == null)
return array( 'title'=>'','data'=>'');
if($type == 'body')
{
$data['articletext'] = base64_decode($data['text']);
}
else
{
$data['articletext'] = strip_tags($data['title']);
}
//update data into link table
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->update($db->quoteName('#__flexicontent_fields_item'))->set($db->quoteName('value').' = '. $db->quote($data['articletext']))->where('field_id = '. (int) $this->id)
->where('item_id'.' = '. (int)$this->id);
$db->setQuery($query);
$db->query();
//Let's save version manually as we cannot use JTableObserverContenthistory in this case!
$typeAlias = 'com_mycck.textarea';
$contenthistoryHelper = new JHelperContenthistory($typeAlias); $this->table->id = $thi->id + $this->item_id
//Set description field so that is displayed in Joomla's version Manager preview screen
$this->table->description = $data['articletext'];
$contenthistoryHelper->store($this->table);
$this->table->id = $this->id; //reset id
//We need to process data as we are sending it back to the client
$item = new stdclass;
$item->text = $data['articletext'];
$item->filed_id = $this->id;
$item->item_id = $this->item_id;
$params = new JObject;
$params->set('inline',false); //set this so that we don't trigger the inline content plugins
//let's detect if any plugin tags are being used
//if so let's inform the system to warn the user
$message = $this->detectPluginTags($item->text);
$dispatcher = JEventDispatcher::getInstance();
JPluginHelper::importPlugin('content');
$dispatcher->trigger('onContentPrepare', array ('com_mycck.textarea', &$item, &$params, 0));
return array( 'title'=>$item->text,'data'=>$item->text,'message'=>$message);
}
You may have noticed that we set the description property of the MyCCKFields JTable instance. We do this because we have explicitly told the Joomla Version Manager, that the description field is one of the properties that should be displayed on the preview screen, by listing it in our XML file. The description field does not exist in the database, so, we have to manually add it to our MyCCKFields instance.
And again, the version method is virtually identical to the code implementation in the Item context class.
public function version($versionId,$type)
{
$historyTable = JTable::getInstance('Contenthistory');
$historyTable->load($versionId);
$rowArray = JArrayHelper::fromObject(json_decode($historyTable->version_data));
$item = $this->table;
$item->bind($rowArray);
if($type == 'title')
{
return array( 'data'=>$item->title);
}
$text = '';
$text = $item->display;
return array( 'data'=>$text);
}
So, putting it all together, your extra field class should look like this:
class ARKContextsMyCCKTextarea extends ARKContextsBase
{
public function __construct($id)
{
JTable::addIncludePath(JPATH_ADMINISTRATOR.'/components/com_mycck/tables');
list($item_id,$id) = explode('_',$id);
$this->table = JTable::getInstance('fields','MyCCK');
$this->table->load($id);
$this->table->item_id = $item_id;
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('value')
->from('#__mycck_fields_item')
->where('field_id = '.(int)$id)
->where('item_id = '.(int)$item_id);
$db->setQuery($query);
$value = $db->loadResult();
$this->table->text = $value;
$this->table->title = '';
$this->item = JTable::getInstance('items','MyCCK');
$this->item->load($item_id);
parent::__construct($id);
}
public function get()
{
if($this->id == null)
return parent::get();
$this->table->articletext = $this->table->text;
return parent::get();
}
public function triggerContentPlugins($rawText)
{
$item = new stdclass;
$item->text = '';
if(isset($rawText))
{
$item->text = $rawText;
$item->file_id = $this->id;
$item->item_id = $this->item_id;
$params = new JObject;
$params->set('inline',false); //set this so that we don't trigger the inline content plugins
$dispatcher = JEventDispatcher::getInstance();
JPluginHelper::importPlugin('content');
$dispatcher->trigger('onContentPrepare', array ('com_mycck.textarea', &$item, &$params, 0));
}
return array( 'data'=>$item->text);
}
public function save($data,$type = 'body')
{
if($this->id == null)
return array( 'title'=>'','data'=>'');
if($type == 'body')
{
$data['articletext'] = base64_decode($data['text']);
}
else
{
$data['articletext'] = strip_tags($data['title']);
}
//update data into link table
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query->update($db->quoteName('#__flexicontent_fields_item'))->set($db->quoteName('value').' = '. $db->quote($data['articletext']))->where('field_id = '. (int) $this->id)
->where('item_id'.' = '. (int)$this->id);
$db->setQuery($query);
$db->query();
//Let's save version manually as we cannot use JTableObserverContenthistory in this case!
$typeAlias = 'com_mycck.textarea';
$contenthistoryHelper = new JHelperContenthistory($typeAlias);
//Set description field so that is displayed in Joomla's version Manager preview screen
$this->table->description = $data['articletext'];
$contenthistoryHelper->store($this->table);
//We need to process data as we are sending it back to the client
$item = new stdclass;
$item->text = $data['articletext'];
$item->file_id = $this->id;
$item->item_id = $this->item_id;
$params = new JObject;
$params->set('inline',false); //set this so that we don't trigger the inline content plugins
//let's detect if any plugin tags are being used
//if so let's inform the system to warn the user
$message = $this->detectPluginTags($item->text);
$dispatcher = JEventDispatcher::getInstance();
JPluginHelper::importPlugin('content');
$dispatcher->trigger('onContentPrepare', array ('com_mycck.textarea', &$item, &$params, 0));
return array( 'title'=>$item->text,'data'=>$item->text,'message'=>$message);
}
public function version($versionId,$type)
{
$historyTable = JTable::getInstance('Contenthistory');
$historyTable->load($versionId);
$rowArray = JArrayHelper::fromObject(json_decode($historyTable->version_data));
$item = $this->table;
$item->bind($rowArray);
if($type == 'title')
{
return array( 'data'=>$item->title);
}
$text = '';
$text = $item->display;
return array( 'data'=>$text);
}
}