Custom Article Field not showing up in joomla 3.2 - php

I've been trying to create a form in the article component backend, so that I can add few things attributes per article. I got this sample code from the joomla website documentation. http://docs.joomla.org/Adding_custom_fields_to_the_article_component
I understand the method onContentPrepareForm is an important function which adds this form in the joomla article backend. However, it doesn't appear for me. I somehow checked global other options and I got to see that the form comes up in the global article options as a seperate tab. However I'd like to add this form for each article.
The version of joomla I am using is 3.2 ...
Btw I have enabled the plugin in the backend ...
<?php
/**
* #package Joomla.Site
* #subpackage plg_content_rating
* #copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
* #license GNU General Public License version 2 or later; see LICENSE.txt
*/
defined('JPATH_BASE') or die;
jimport('joomla.utilities.date');
/**
* An example custom profile plugin.
*
* #package Joomla.Plugin
* #subpackage User.profile
* #version 1.6
*/
class plgContentRating extends JPlugin
{
/**
* Constructor
*
* #access protected
* #param object $subject The object to observe
* #param array $config An array that holds the plugin configuration
* #since 2.5
*/
public function __construct(& $subject, $config)
{
parent::__construct($subject, $config);
$this->loadLanguage();
}
/**
* #param string $context The context for the data
* #param int $data The user id
* #param object
*
* #return boolean
* #since 2.5
*/
function onContentPrepareData($context, $data)
{
if (is_object($data))
{
$articleId = isset($data->id) ? $data->id : 0;
if (!isset($data->rating) and $articleId > 0)
{
// Load the profile data from the database.
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('profile_key, profile_value');
$query->from('#__user_profiles');
$query->where('user_id = ' . $db->Quote($articleId));
$query->where('profile_key LIKE ' . $db->Quote('rating.%'));
$query->order('ordering');
$db->setQuery($query);
$results = $db->loadRowList();
// Check for a database error.
if ($db->getErrorNum())
{
$this->_subject->setError($db->getErrorMsg());
return false;
}
// Merge the profile data.
$data->rating = array();
foreach ($results as $v)
{
$k = str_replace('rating.', '', $v[0]);
$data->rating[$k] = json_decode($v[1], true);
if ($data->rating[$k] === null)
{
$data->rating[$k] = $v[1];
}
}
}
}
return true;
}
/**
* #param JForm $form The form to be altered.
* #param array $data The associated data for the form.
*
* #return boolean
* #since 2.5
*/
function onContentPrepareForm($form, $data)
{
if (!($form instanceof JForm))
{
$this->_subject->setError('JERROR_NOT_A_FORM');
return false;
}
/* if (!in_array($form->getName(), array('com_content.article'))) {
return true;
}*/
// Add the extra fields to the form.
// need a seperate directory for the installer not to consider the XML a package when "discovering"
JForm::addFormPath(dirname(__FILE__) . '/rating');
$form->loadFile('rating',false);
return true;
}
/**
* Example after save content method
* Article is passed by reference, but after the save, so no changes will be saved.
* Method is called right after the content is saved
*
* #param string The context of the content passed to the plugin (added in 1.6)
* #param object A JTableContent object
* #param bool If the content is just about to be created
* #since 2.5
*/
public function onContentAfterSave($context, &$article, $isNew)
{
$articleId = $article->id;
if ($articleId && isset($article->rating) && (count($article->rating)))
{
try
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->delete('#__user_profiles');
$query->where('user_id = ' . $db->Quote($articleId));
$query->where('profile_key LIKE ' . $db->Quote('rating.%'));
$db->setQuery($query);
if (!$db->query()) {
throw new Exception($db->getErrorMsg());
}
$query->clear();
$query->insert('#__user_profiles');
$order = 1;
foreach ($article->rating as $k => $v)
{
$query->values($articleId.', '.$db->quote('rating.'.$k).', '.$db->quote(json_encode($v)).', '.$order++);
}
$db->setQuery($query);
if (!$db->query()) {
throw new Exception($db->getErrorMsg());
}
}
catch (JException $e)
{
$this->_subject->setError($e->getMessage());
return false;
}
}
return true;
}
/**
* Finder after delete content method
* Article is passed by reference, but after the save, so no changes will be saved.
* Method is called right after the content is saved
*
* #param string The context of the content passed to the plugin (added in 1.6)
* #param object A JTableContent object
* #since 2.5
*/
public function onContentAfterDelete($context, $article)
{
$articleId = $article->id;
if ($articleId)
{
try
{
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->delete();
$query->from('#__user_profiles');
$query->where('user_id = ' . $db->Quote($articleId));
$query->where('profile_key LIKE ' . $db->Quote('rating.%'));
$db->setQuery($query);
if (!$db->query())
{
throw new Exception($db->getErrorMsg());
}
}
catch (JException $e)
{
$this->_subject->setError($e->getMessage());
return false;
}
}
return true;
}
public function onContentPrepare($context, &$article, &$params, $page = 0)
{
if (!isset($article->rating) || !count($article->rating))
return;
// add extra css for table
$doc = JFactory::getDocument();
$doc->addStyleSheet(JURI::base(true).'/plugins/content/rating/rating/rating.css');
// construct a result table on the fly
jimport('joomla.html.grid');
$table = new JGrid();
// Create columns
$table->addColumn('attr')
->addColumn('value');
// populate
$rownr = 0;
foreach ($article->rating as $attr => $value) {
$table->addRow(array('class' => 'row'.($rownr % 2)));
$table->setRowCell('attr', $attr);
$table->setRowCell('value', $value);
$rownr++;
}
// wrap table in a classed <div>
$suffix = $this->params->get('ratingclass_sfx', 'rating');
$html = '<div class="'.$suffix.'">'.(string)$table.'</div>';
$article->text = $html.$article->text;
}
}
EDIT POST:
I added this code to /administrator/components/com_content/views/article/tmpl/edit.php
<?php
$i = 0;
$fieldSets = $this->form->getFieldsets();
foreach ($fieldSets as $name => $fieldSet) :
if($i <= 3){
$i++;
continue;
}
echo JHtml::_('bootstrap.addTab', 'myTab', $fieldSet->name, JText::_($fieldSet->label, true));
?>
<div class="tab-pane" id="<?php echo $name;?>">
<?php
if (isset($fieldSet->description) && !empty($fieldSet->description)) :
echo '<p class="tab-description">'.JText::_($fieldSet->description).'</p>';
endif;
foreach ($this->form->getFieldset($name) as $field):
?>
<div class="control-group">
<?php if (!$field->hidden && $name != "permissions") : ?>
<div class="control-label">
<?php echo $field->label; ?>
</div>
<?php endif; ?>
<div class="<?php if ($name != "permissions") : ?>controls<?php endif; ?>">
<?php echo $field->input; ?>
</div>
</div>
<?php
endforeach;
?>
</div>
<?php echo JHtml::_('bootstrap.endTab'); ?>
<?php endforeach; ?>

As you've mentioned the core tmpl file won't support your changes.
Hacking the core files (as you've done) is a very bad idea for several reason, including that they could be overwritten when the next 3.2.x security patch is released (like the upcoming 3.2.1) and most certainly will be when 3.5 is released. Given the rapidity Joomla releases security patches and their regular 1-click Major and Minor update cycle the last thing you want to be worrying about is your changes being blown away.
Luckily Joomla lets you create template overrides, the process for admin is pretty much the same as overrides for front-end templates.
Luckily for you the modification is in the right file, assuming you're using the default Admin template Isis simply copy
/administrator/components/com_content/views/article/tmpl/edit.php
to:
/administrator/templates/isis/html/com_content/article/edit.php
You may want to revert your original file but as mentioned it's almost certainly to get updated in either a security update or version update.

found a solution to your problem (and mine) in another article here solution to your problem hope it helps. It appears that the example plugin contains an error

Related

Simple PHP template class

I wanted separate my HTML from PHP so after searching I found a great little php class that just do the trick. Only issue that I try merging 2 templates together but it doesn’t work.
Here is the original class that i found from below website
http://www.broculos.net/2008/03/how-to-make-simple-html-template-engine.html#.WCsa8CTy2ng
class Template {
/**
* The filename of the template to load.
*
* #access protected
* #var string
*/
protected $file;
/**
* An array of values for replacing each tag on the template (the key for each value is its corresponding tag).
*
* #access protected
* #var array
*/
protected $values = array();
/**
* Creates a new Template object and sets its associated file.
*
* #param string $file the filename of the template to load
*/
public function __construct($file) {
$this->file = $file;
}
/**
* Sets a value for replacing a specific tag.
*
* #param string $key the name of the tag to replace
* #param string $value the value to replace
*/
public function set($key, $value) {
$this->values[$key] = $value;
}
/**
* Outputs the content of the template, replacing the keys for its respective values.
*
* #return string
*/
public function output() {
/**
* Tries to verify if the file exists.
* If it doesn't return with an error message.
* Anything else loads the file contents and loops through the array replacing every key for its value.
*/
if (!file_exists($this->file)) {
return "Error loading template file ($this->file).<br />";
}
$output = file_get_contents($this->file);
foreach ($this->values as $key => $value) {
$tagToReplace = "[#$key]";
$output = str_replace($tagToReplace, $value, $output);
}
return $output;
}
/**
* Merges the content from an array of templates and separates it with $separator.
*
* #param array $templates an array of Template objects to merge
* #param string $separator the string that is used between each Template object
* #return string
*/
static public function merge($templates, $separator = "\n") {
/**
* Loops through the array concatenating the outputs from each template, separating with $separator.
* If a type different from Template is found we provide an error message.
*/
$output = "";
foreach ($templates as $template) {
$content = (get_class($template) !== "Template")
? "Error, incorrect type - expected Template."
: $template->output();
$output .= $content . $separator;
}
return $output;
}
}
Code that work
$post = new Template("post.tpl");
$post->set("post_title", $post_title);
$post->set("post_description", $post_description);
$post->set("content", $post->output());
echo $post->output();
Even when I want to loop if I add the code it works fine. But then I try to merge two template files together
all_posts.tpl
<div class=”posts”>
<h1>[#page_title]</</h1>
[#display_posts]
</div>
display_posts.tpl
<div class=”post”>
<h2>[#display_title]</h2>
<p>[#display_description]</p>
</div>
So what I want to do now is to push display_posts.tpl to all_posts.tpl and replace the tag [#display_posts]
So in my php I did below
$post = new Template("all_posts.tpl ");
$post->set("page_title", "All Posts");
echo $post->output();
//created a array from a mysqli loop
$post_set = array();
while ($post_row = mysqli_fetch_array($posts)){
$post_title = $post_row['title'];
$post_description = $post_row['description'];
$post_set[] = array(
"display_title" => $post_title,
"display_description" => $post_description
);
}
foreach ($post_set as $posts) {
$row = new Template("list_users_row.tpl");
foreach ($posts as $key => $value) {
$row->set($key, $value);
}
$postsTemplates[] = $posts;
}
// here i try to merge template
$postsContents = Template::merge($postsTemplates);
$layout->set("content", $postsContents->output());
echo $layout->output();
But this is throwing off a error set() is not an function. Could someone help me out to figure out this? I’m still in the process of learning php classes.
The reason why $layout->set() does not work is because $layout is not a Template Object. In your code you use $post = new Template("all_posts.tpl ");. This makes $post a Template object that can use the set() function in your Template class.
So you should do: $layout = new Template(....) and than you can call $layout->set().
In the tutorial they do the same:
include("template.class.php");
$profile = new Template("user_profile.tpl");
$profile->set("username", "monk3y");
$profile->set("photoURL", "photo.jpg");
$profile->set("name", "Monkey man");
$profile->set("age", "23");
$profile->set("location", "Portugal");
$layout = new Template("layout.tpl");
$layout->set("title", "User profile");
$layout->set("content", $profile->output());
echo $layout->output();
Hope this helps.

Joomla plugin unique alias

I need to auto-generate different aliases from two articles with the same title in Joomla 3.3. The user will add articles in the front end. I found this code:
<?php
defined( '_JEXEC' ) or die;
class plgContentRandom_Alias extends JPlugin
{
function onContentBeforeSave($context, &$article, $isNew) {
if(!$isNew){
return;
}
$alias = $article->alias;
$n = substr( "abcdefghijklmnopqrstuvwxyz" ,mt_rand( 0 ,25 ) ,1 ) .substr( md5( time( ) ) ,1 );
$table = JTable::getInstance('content');
while ($table->load(array('alias' => $alias))) {
$new_alias = $alias . $n;
}
$article->alias = $new_alias;
return true;
}
}
?>
, and made a plugin for Joomla, but the plugin not working in Joomla 3.3.
Any suggestions?
You can write your own plugin using the following code, although this functionality should be already part of joomla core.
I've used this because of Seblod error when using its insert content form.
Files:
Joomla installer descriptor:
uniqueAliasGenerator.xml
<?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="content" method="upgrade">
<name>Content - Unique alias generator</name>
<author>McGiogen</author>
<creationDate>May 2015</creationDate>
<copyright></copyright>
<license></license>
<authorEmail>mcgiogen#hotmail.it</authorEmail>
<authorUrl>www.joomla.org</authorUrl>
<version>1.0</version>
<description>
Automatic generator of unique alias.
At save time it append "-X" (where X is a numeric identifier)
if article alias is already in database.
</description>
<files>
<filename plugin="uniqueAliasGenerator">uniqueAliasGenerator.php</filename>
<filename>index.html</filename>
</files>
<config>
</config>
</extension>
Plugin code:
uniqueAliasGenerator.php
<?php
// no direct access
defined( '_JEXEC' ) or die( 'Restricted access' );
class plgContentUniqueAliasGenerator extends JPlugin
{
/**
* Alias check and generation before save content method.
* Content is passed by reference. Method is called before the content is saved.
*
* #param string $context The context of the content passed to the plugin (added in 1.6).
* #param object $article A JTableContent object.
* #param bool $isNew If the content is just about to be created.
*
* #return void
*/
public function onContentBeforeSave($context, $article, $isNew)
{
if ($context == 'com_content.article' && $article->alias && $isNew) {
$oldAlias = $article->alias;
$categoryId = $article->catid; //An alias must be unique only in its category
$article->alias = $this->getUniqueAlias($oldAlias, $categoryId);
}
return true;
}
/**
* Find unique Alias name if current doesn't exist.
* #param string $alias Alias of the article
* #param string $catId Id of article's category
*
* #return string Return the unique alias value.
*/
protected function getUniqueAlias($alias, $catId)
{
$alias_ini = $alias;
for ($i = 2; $this->isAliasExist($alias, $catId); $i++) {
$alias = $alias_ini . '-' . $i;
}
return $alias;
}
/**
* Check the 'alias' in the database.
*
* #return boolean If found return true else false.
*/
protected function isAliasExist($alias, $catId)
{
$db = JFactory::getDBO();
$query = $db->getQuery(true);
$query
->select('COUNT(*)')
->from($db->quoteName('#__content')) //Articles table
->where($db->quoteName('alias') . ' = ' . $db->quote($alias))
->where($db->quoteName('catid') . ' = ' . $db->quote($catId)); //Category ID
$db->setQuery($query);
return ($db->loadResult() ? true : false);
}
}
?>
index.html
<!DOCTYPE html><title></title>
How to use:
Create files with the same names, put them in a folder called "uniqueAliasGenerator", zip in "uniqueAliasGenerator.zip", upload and install on your joomla.
Compatible with Joomla 3.x, tested on Joomla 3.4.1
Update 11 Nov 2017
Added check of $isNew. Thanks #robert-drygas.
In McGiogen code the line
if ($context == 'com_content.article' && $article->alias) {
can be write as
if ($context == 'com_content.article' && $article->alias && $isNew) {
so unique alias will be ganerated only for the new articles (without altered existing aliases when editing old articles).

Getting data from model with custom component for Joomla

So I've been trying to get data from a single item from the database using the MVC method in Joomla. I've been inspecting com_content how to do this, but I can't seem to get the id from the URL
This is my model to get the data for a single item
<?php
// No direct access to this file
defined('_JEXEC') or die('Restricted access');
// import Joomla modelitem library
jimport('joomla.application.component.modelitem');
/**
* Issuu Model
*/
class IssuuModelItem extends JModelItem
{
/**
* #var string msg
*/
protected $item;
/**
* Method to auto-populate the model state.
*
* Note. Calling getState in this method will result in recursion.
*
* #since 1.6
*
* #return void
*/
protected function populateState()
{
$app = JFactory::getApplication('site');
// Load state from the request.
$id = $app->input->getInt('id');
$this->setState('item.id', $id);
$offset = $app->input->getUInt('limitstart');
$this->setState('list.offset', $offset);
// Load the parameters.
$params = $app->getParams();
$this->setState('params', $params);
// TODO: Tune these values based on other permissions.
$user = JFactory::getUser();
if ((!$user->authorise('core.edit.state', 'com_issuu')) && (!$user->authorise('core.edit', 'com_issuu')))
{
$this->setState('filter.published', 1);
$this->setState('filter.archived', 2);
}
$this->setState('filter.language', JLanguageMultilang::isEnabled());
}
/**
* Returns a reference to the a Table object, always creating it.
*
* #param type The table type to instantiate
* #param string A prefix for the table class name. Optional.
* #param array Configuration array for model. Optional.
* #return JTable A database object
* #since 2.5
*/
public function getTable($type = 'Item', $prefix= 'IssuuTable', $config = array()) {
return JTable::getInstance($type,$prefix,$config);
}
/**
* Get the message
* #return string The message to be displayed to the user
*/
public function getItem($id = null)
{
$id = (!empty($id)) ? $id : (int) $this->getState('item.id');
if(!is_array($this->item)) {
$this->item = array();
}
// Get a db connection.
$db = JFactory::getDbo();
// Create a new query object.
$query = $db->getQuery(true);
// Select all records from the user profile table where key begins with "custom.".
// Order it by the ordering field.
$query->select($db->quoteName(array('id', 'title', 'username', 'docname', 'docid','date', 'pages', 'description')));
$query->from($db->quoteName('#__issuu_publications'));
$query->where($db->quoteName('state') . ' = `1` AND ' . $db->quoteName('id') . ' = ' . $db->qouteName($id));
$query->order('date ASC');
// Reset the query using our newly populated query object.
$db->setQuery($query);
// Load the results as a list of stdClass objects (see later for more options on retrieving data).
$this->items = $db->loadObjectList();
return $this->items;
}
}
I get a SQL error because the $id is empty.. (I removed the prefix from the table)
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ORDER BY date ASC' at line 4 SQL=SELECT `id`,`title`,`username`,`docname`,`docid`,`date`,`pages`,`description` FROM `#__issuu_publications` WHERE `state` = `1` AND `id` = ORDER BY date ASC
Any help is appreciated!
Try replacing your where clause with the following:
$query->where($db->quoteName('state') . ' = 1 AND ' . $db->quoteName('id') . ' = ' . $db->quote((int) $id));
I've removed the quotes around 1
replaced $id with (int) $id
And corrected a spelling mistake on quoteName

SimpleBrowser returns empty html

I am using SimpleBrowser that is a part of SimpleTest PHP framework.
The idea is to imitate user interactions with the website and record returned HTML code into a file for further comparison. But something goes wrong here as empty HTML is sometimes returned.
getTransportError() returns Nothing fetched
It happens in completely random places and I can't use back() function because most pages are submitted forms.
require_once('simpletest/browser.php');
class TesterBrowser extends SimpleBrowser
{
/**
* Test the page against the reference. If reference is missing, is it created
* Uses md5 checksum to check if files are identical
*
* #param string $forcename Optional. Substitude autogenerated filename.
* #param boolean $forceRef Optional. Force file to be saved as the reference
*
* #access public
*
* #return void
*/
public function testPage($forcename = "")
{
//who called me?
//$callers=debug_backtrace();
//$whocalledme = $callers[1]['function'];
//get the current source
$html = $this->getContent();
//generate filename
$filename = empty($forcename) ? preg_replace('/[^\w\-'. ''. ']+/u', '-', $this->getUrl()) : $forcename;
$filename .= ".html";
//is there a gauge?
if(file_exists("ref/".$filename) && filesize(dirname(__FILE__)."/ref/".$filename) > 0)
{
//is there a difference
file_put_contents(dirname(__FILE__)."/actual/".$filename, $html);
if(filesize(dirname(__FILE__)."/actual/".$filename) == 0)
{
return false;
}
if(md5_file(dirname(__FILE__)."/actual/".$filename) != md5_file(dirname(__FILE__)."/ref/".$filename))
{
echo $this->getUrl() . " (" . $filename . ") has changed \r\n";
}
}
else
{
file_put_contents(dirname(__FILE__)."/ref/".$filename, $html);
if(filesize(dirname(__FILE__)."/ref/".$filename) == 0)
{
return false;
}
}
return true;
}
/**
* Output the string to the terminal
*
* #param mixed $string String to output
*
* #access public
*
* #return void
*/
public function output($string)
{
echo date("d-m-Y H:i:s") . " - $string... \r\n";
//update date so that it will be the same on every page
exec('date -s "24 JUN 2013 10:00:00"');
}
/**
* Restore the server date using external NTP server
*
* #access public
*
* #return void
*/
public function restoreDate(){
$this->output("Restoring the date&time from NTP server");
exec("ntpdate 0.uk.pool.ntp.org");
exec("hwclock -systohc");
}
}
And the way tests are performed:
class Tester
{
public $browser = null;
const BASEURL = "http://ticketing/";
function __construct(){
$this->browser = new TesterBrowser();
$this->browser->setConnectionTimeout(180);
//get the list of class method to be run
$methods = array();
foreach(get_class_methods($this) as $var)
{
if(0 === strpos($var, 'test')) //they all start with test
{
$methods[] = $var;
}
}
$methods[] = "cleanUp";
//now we need to run these methods
foreach($methods as $m){
while($this->$m() == false){
$this->browser->output("Empty page, trying again");
sleep(5);
}
}
}
//index page
function testGetIndexPage()
{
$this->browser->output("Getting index page");
$this->browser->get(self::BASEURL);
return $this->browser->testPage();
}
//try to enter wrong password
function testWrongPassword()
{
$this->browser->output("Entering wrong credentials");
$this->browser->setField("username", "wrong");
$this->browser->setField("password", "wrong");
$this->browser->clickSubmitByName("submit");
return $this->browser->testPage("wrong-credentials");
}
//Delete ticket though admin
function testDeleteTicketThroughAdmin()
{
$this->browser->output("Deleting the ticket through admin page");
$this->browser->setField("bulk[]", "375341");
$this->browser->setField("bulkaction", "delete");
$this->browser->clickSubmit("Do Action");
return $this->browser->testPage("deleted-ticket-admin");
}
//Restore the date
function cleanUp()
{
$this->browser->restoreDate();
return true;
}
}
$tester = new Tester();
There are of course much more test performed and this is a stripped version.
I have googled a lot about this problem, there seems to be no adequate documentation whatsoever.
Solved. It was a timeout issue although for some reason no adequate error message is implemented.
$this->browser->setConnectionTimeout(180);

How to add a link category_id added to the admin (JToolBarHelper::addNew)? - Joomla 2.5

How to add a link category_id added to the admin? (Joomla 2.5)
You could write in the function JToolBarHelper::addNew('select.add'); or other functions...
For example,
index.php?option=com_pictures&view=select&layout=edit&category_id=14
Help, please. Thanks in advance
Reply David F:
Hi, David F. I almost got it.
After clicking "Add" appears category_id=14, and the rest did not work after clicking "Edit", "Save", "Save Close" ... - category_id=0
I've been programming. Here's an example:
...
protected $catid;
public function __construct($config = array()) {
parent::__construct($config);
if (empty($this->catid)) {
$this->catid = JRequest::getInt('category_id', 0);
}
}
protected function allowAdd($data = array()) {
$user = JFactory::getUser();
$categoryId = JArrayHelper::getValue($data, 'catid', JRequest::getInt('filter_category_id'), 'int');
$allow = null;
if ($categoryId) {
$allow = $user->authorise('core.create', $this->option . '.category.' . $categoryId);
}
if ($allow === null) {
return parent::allowAdd($data);
} else {
return $allow;
}
}
protected function allowEdit($data = array(), $key = 'id') {
$recordId = (int) isset($data[$key]) ? $data[$key] : 0;
$categoryId = 0;
if ($recordId) {
$categoryId = (int) $this->getModel()->getItem($recordId)->catid;
}
if ($categoryId) {
return JFactory::getUser()->authorise('core.edit', $this->option . '.category.' . $categoryId);
} else {
return parent::allowEdit($data, $key);
}
}
protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id') {
$append = parent::getRedirectToItemAppend($recordId);
$append .= '&category_id=' . $this->category_id;
return $append;
}
protected function getRedirectToListAppend() {
$append = parent::getRedirectToListAppend();
$append .= '&category_id=' . $this->category_id;
return $append;
}
I believe that the functions that you are looking for are part of JController and should be added to your controller. In your case, this would likely be the select.php controller based on the view name in your url.
You can see a good example of this in the categories component, specifically at administrator/components/com_categories/controllers/category.php.
The following is the code in com_categories. You would want to rename extension to 'category_id' and may want to grab the value from JInput instead of the current class:
/**
* Gets the URL arguments to append to an item redirect.
*
* #param integer $recordId The primary key id for the item.
* #param string $urlVar The name of the URL variable for the id.
*
* #return string The arguments to append to the redirect URL.
*
* #since 1.6
*/
protected function getRedirectToItemAppend($recordId = null, $urlVar = 'id')
{
$append = parent::getRedirectToItemAppend($recordId);
$append .= '&extension=' . $this->extension;
return $append;
}
/**
* Gets the URL arguments to append to a list redirect.
*
* #return string The arguments to append to the redirect URL.
*
* #since 1.6
*/
protected function getRedirectToListAppend()
{
$append = parent::getRedirectToListAppend();
$append .= '&extension=' . $this->extension;
return $append;
}
*EDIT:
You also have to add it as part of the form. This is the easy, but important part. Just make sure the form has a hidden input with the value or add it to the url in the action section of the form:
<form action="<?php echo JRoute::_('index.php?option=com_component&layout=edit&id='.(int) $this->item->id . '&category_id='.$this->category_id); ?>" method="post" name="adminForm">
or use this:
<input type="hidden" name="category_id" value="<?php echo $this->category_id; ?>" />
To further explain what happens, when you click an item to go to the form, you likely add on the variable that you need. Then you add it to the form so that when one of the items is clicked, it will get submitted with the form. Joomla processes this form and either saves it or not depending on the toolbar button clicked. Then Joomla redirects, either back to the form or to the list view. Without the functions in your controller, your variable gets lost.

Categories