In WordPress How can I get the URL of the parent post (for a kind of Up button)?
This is the code I'm using to pull the parent name:
<?php
if( empty($wp_query->post->post_parent) ) {
$parent_post_id = $wp_query->post->ID;
} else {
$parent_post_id = $wp_query->post->post_parent;
}
$parent_post = get_post($parent_post_id);
$parent_post_title = $parent_post->post_title;
echo $parent_post_title;
Use get_permalink($postid):
global $post;
$parentId = $post->post_parent;
$linkToParent = get_permalink($parentId);
This is an alternate method I use, which gets the parent page permalink based on the current permalink path instead of the $post->page_parent property:
/**
* Get the parent permalink based on the url path
*
* #param $id int
* #return str
*/
function get_parent_permalink($id = false) {
$id = !$id ? get_the_id() : $id;
return str_replace(basename(get_permalink($id)) . '/', '', get_permalink($id));
}
Related
I am trying to extend the WP class WP_List_Table within a plugin.
I am using the code found below. When I excecute my script I get the following message:
"Fatal error: Uncaught Error: Call to undefined function
convert_to_screen() in
/home/u794297373/domains/educoder.dk/public_html/lessannoyingcmsforwp/wp-admin/includes/class-wp-list-table.php:149
Stack trace:
#0
/home/u794297373/domains/educoder.dk/public_html/lessannoyingcmsforwp/wp-content/plugins/lessannoyingcrmforwp/inc/API/Functions/LinkListTableFront.php(23):
WP_List_Table->__construct(Array)
#1
/home/u794297373/domains/educoder.dk/public_html/lessannoyingcmsforwp/wp-content/plugins/lessannoyingcrmforwp/inc/Base/SearchContactsFunctionController.php(33):
Inc\API\Functions\LinkListTableFront->__construct()
#2
/home/u794297373/domains/educoder.dk/public_html/lessannoyingcmsforwp/wp-content/plugins/lessannoyingcrmforwp/inc/Init.php(33):
Inc\Base\SearchContactsFunctionController->register()
#3
/home/u794297373/domains/educoder.dk/public_html/lessannoyingcmsforwp/wp-content/plugins/lessannoyingcrmforwp/lessannoyingcrmforwp.php(55):
Inc\Init::register_services()
#4
/home/u794297373/domains/educoder.dk/public_html/lessannoyi in
/home/u794297373/domains/educoder.dk/public_html/lessannoyingcmsforwp/wp-admin/includes/class-wp-list-table.php
on line 149"
The line referred to calls the function "convert_to_screen()"
I can't semm to figure out what is going wrong?
The controller code:
<?php
/**
* #package LessAnnoyingCRMforWP
*/
namespace Inc\API\Functions;
if(!class_exists('WP_List_Table')){
require_once( ABSPATH . 'wp-admin/includes/screen.php' );
require_once( ABSPATH . 'wp-admin/includes/class-wp-list-table.php' );
}
class LinkListTableFront extends \WP_List_Table
{
/**
* Constructor, we override the parent to pass our own arguments
* We usually focus on three parameters: singular and plural labels, as well as whether the class supports AJAX.
*/
function __construct() {
parent::__construct( array(
'singular'=> 'wp_list_text_link', //Singular label
'plural' => 'wp_list_test_links', //plural label, also this well be one of the table css class
'ajax' => false //We won't support Ajax for this table
) );
}
/**
* Add extra markup in the toolbars before or after the list
* #param string $which, helps you decide if you add the markup after (bottom) or before (top) the list
*/
function extra_tablenav( $which ) {
if ( $which == "top" ){
//The code that goes before the table is here
echo "Hello, I'm before the table";
}
if ( $which == "bottom" ){
//The code that goes after the table is there
echo "Hi, I'm after the table";
}
}
/**
* Define the columns that are going to be used in the table
* #return array $columns, the array of columns to use with the table
*/
function get_columns() {
return $columns = [
'col_link_id'=>__('ID'),
'col_link_name'=>__('Name'),
'col_link_url'=>__('Url'),
'col_link_description'=>__('Description'),
'col_link_visible'=>__('Visible')
];
}
/**
* Decide which columns to activate the sorting functionality on
* #return array $sortable, the array of columns that can be sorted by the user
*/
public function get_sortable_columns() {
return $sortable = array(
'col_link_id'=>'link_id',
'col_link_name'=>'link_name',
'col_link_visible'=>'link_visible'
);
}
/**
* Prepare the table with different parameters, pagination, columns and table elements
*/
function prepare_items() {
global $wpdb, $_wp_column_headers;
$screen = get_current_screen();
/* -- Preparing your query -- */
$query = "SELECT * FROM $wpdb->links";
/* -- Ordering parameters -- */
//Parameters that are going to be used to order the result
$orderby = !empty($_GET["orderby"]) ? mysql_real_escape_string($_GET["orderby"]) : 'ASC';
$order = !empty($_GET["order"]) ? mysql_real_escape_string($_GET["order"]) : '';
if ( ! empty($orderby) & ! empty($order) ) { $query .= ' ORDER BY ' . $orderby . ' ' . $order; }
/* -- Pagination parameters -- */
//Number of elements in your table?
$totalitems = $wpdb->query($query); //return the total number of affected rows
//How many to display per page?
$perpage = 5;
//Which page is this?
$paged = !empty($_GET["paged"]) ? mysql_real_escape_string($_GET["paged"]) : '';
//Page Number
if(empty($paged) || !is_numeric($paged) || $paged<=0 ){ $paged=1; } //How many pages do we have in total?
$totalpages = ceil($totalitems/$perpage); //adjust the query to take pagination into account
if(!empty($paged) && !empty($perpage)){ $offset=($paged-1)*$perpage; $query.=' LIMIT '.(int)$offset.','.(int)$perpage; }
/* -- Register the pagination -- */
$this->set_pagination_args( array(
"total_items" => $totalitems,
"total_pages" => $totalpages,
"per_page" => $perpage,
) );
//The pagination links are automatically built according to those parameters
/* -- Register the Columns -- */
$columns = $this->get_columns();
$_wp_column_headers[$screen->id]=$columns;
/* -- Fetch the items -- */
$this->items = $wpdb->get_results($query);
}
/**
* Display the rows of records in the table
* #return string, echo the markup of the rows
*/
function display_rows() {
//Get the records registered in the prepare_items method
$records = $this->items;
//Get the columns registered in the get_columns and get_sortable_columns methods
list( $columns, $hidden ) = $this->get_column_info();
//Loop for each record
if(!empty($records)) {
foreach ( $records as $rec) {
//Open the line
echo '< tr id="record_'.$rec->link_id.'">';
foreach ( $columns as $column_name => $column_display_name ) {
//Style attributes for each col
$class = "class='$column_name column-$column_name'";
$style = "";
if ( in_array( $column_name, $hidden ) ) $style = ' style="display:none;"';
$attributes = $class . $style;
//edit link
$editlink = '/wp-admin/link.php?action=edit&link_id='.(int)$rec->link_id;
//Display the cell
switch ( $column_name ) {
case "col_link_id": echo '< td '.$attributes.'>'.stripslashes($rec->link_id).'< /td>'; break;
case "col_link_name": echo '< td '.$attributes.'>'.stripslashes($rec->link_name).'< /td>'; break;
case "col_link_url": echo '< td '.$attributes.'>'.stripslashes($rec->link_url).'< /td>'; break;
case "col_link_description": echo '< td '.$attributes.'>'.$rec->link_description.'< /td>'; break;
case "col_link_visible": echo '< td '.$attributes.'>'.$rec->link_visible.'< /td>'; break;
}
}
//Close the line
echo'< /tr>';
}
}
}
}
SOLVED: The problem was the order of the instantiation. By adding an add_action( 'call', [ $this, 'initClass' ]); The class was called at the correct time.
Then I had a do_action command on the page where I needed to call the list. Apperently the script was called too early in the initial code.
I ended up with the code:
add_action( 'search_for_contact_or_company', [ $this, 'initSearchList' ] );
add_action( 'add_contact', [ $this, 'initCreateContact' ] );
}
public static function initSearchList( $arg ) {
$this->search_list_table = new SearchListTableAdmin();
$searchLess = $arg;
do_action( 'search_for_contact', $searchLess );
}
The initSearchList function then calls the rendering of the code in my SearchListTableAdmin class.
I want to save product id in an array when user opens a product page, and then save that array in a cookie. This is my code:
if(is_product()) {
if(isset($_COOKIE['recent'])) {
$data = unserialize($_COOKIE['recent']);
$product_id = get_the_ID();
if(!in_array($product_id, $data)) {
array_unshift($data, $product_id);
if(count($data) > 8) {
array_pop($data);
}
setcookie('recent', serialize($data), time()+(3600*24*7), "/");
}
echo "SET";
}else{
$data = array();
$product_id = get_the_ID();
array_unshift($data, $product_id);
setcookie('recent', serialize($data), time()+(3600*24*7), "/");
echo "DIDNT SET";
}
print_r($data);
}
Those echos and print_r is for debugging purposes. So if it is a product page, I check whether cookie is already set, if yes, then I just want to add product ID to the array if it is already there and update the value. And if cookie is not set, I'm creating a new array and then printing content of $data.
The problem is, that all, except one product page works fine. For example I can browse through products and see that it prints out the same array over and over again, but one product page has its own array of IDs, which is array of one element - that product element. That product page has no different URL from others. same pattern: website.com/product/productname/
It seems like it has its own scope. Even tough I used "/" for the domain, so I guess it should be the same across all the website?
What is wrong here?
I tested this locally and had similar results. The reason you were getting the output errors in your header was because you were trying to set the initial cookie with an integer instead of a string. That and the WP headers were initialized but the query had not fully processed.
I made a plugin that will run on the template_redirect hook which will allow you to debug much easier. There's also a [recently_viewed] shortcode that'll let you do something with your actual result.
You can drop this in your theme or create a recently_viewed.php in your plugins folder:
https://gist.github.com/simplethemes/4f9b6f969bcc0a0a6668aeed75491a15
/*
Plugin Name: Set Shop Cookie
Description: Adds a cookie for most recently viewed products
Version: 0.1
Author: Casey Lee
Author URL: https://simplethemes.com
*/
class SetWpShopCookie {
/**
* #var string API URL
*/
public static $instance;
public $recent_cookie;
public $cookie_name = 'recent';
public $recent_products;
/** Hook WordPress
* #return void
*/
public function __construct()
{
self::$instance = $this;
add_action( 'template_redirect', array( $this, 'get_recent_cookie') );
add_action( 'template_redirect', array( $this, 'set_post_cookie') );
add_shortcode( 'recently_viewed', array( $this, 'recent_products') );
}
/**
* Gets the 'recent' cookie
* #return array or null
*/
public function get_recent_cookie()
{
$recent_cookie = null;
$cookies = array();
foreach ( $_COOKIE as $name => $value ) {
$cookies[] = new WP_Http_Cookie( array( 'name' => $name, 'value' => $value ) );
}
foreach($cookies as $cookie) {
if ($this->cookie_name == $cookie->name) {
$recent_cookie = $cookie;
break;
}
}
$this->recent_cookie = $recent_cookie;
}
/**
* Load scripts when plugin is executed
* #see https://developer.wordpress.org/reference/classes/wp_http_cookie/
*/
public function set_post_cookie()
{
global $post;
$product_id = $post->ID;
$cookie_time = time() + 60 * 60 * 24 * 7;
// nothing to do here if we're not in a product single
if (!is_product())
return;
// create the cookie
if(!$this->recent_cookie) {
$data = array();
array_unshift($data, $product_id);
setcookie($this->cookie_name, serialize($data), $cookie_time, COOKIEPATH, COOKIE_DOMAIN);
// update existing cookie
} else {
$data = unserialize($this->recent_cookie->value);
if(!in_array($product_id, $data)) {
array_unshift($data, $product_id);
if(count($data) > 8) {
array_pop($data);
}
// Use WP globals for portable cookie settings
setcookie($this->cookie_name, serialize($data), $cookie_time, COOKIEPATH, COOKIE_DOMAIN);
}
}
// Debug
// var_dump($this->recent_cookie);
}
// Recently viewed products shortcode
function recent_products( $atts ) {
// Attributes
$atts = shortcode_atts(
array(
'count' => '5',
),
$atts,
'recently_viewed'
);
$product_data = unserialize($this->recent_cookie->value);
$str = '';
if ($product_data) {
foreach ($product_data as $products_viewed) {
$str .= $products_viewed .' ,';
}
return 'You recently viewed these products: ' . rtrim($str,',');
} else {
return 'Why don\'t you visit our shop?';
}
}
}
new SetWpShopCookie;
It's difficult to say without seeing your output. Try posting a dump of your $data in the context you mention. get_the_ID() is a proxy through get_post(), so you might try setting the ID more reliably with the below. At least then you'll see an error if you don't have a proper object.
global $product;
$product_id = $product->id;
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).
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
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.