Drupal 8 - Programmatically disable or enable link on main navigation - php

This concerns Drupal 8.
I'm trying to manage a link item on the main navigation. I want to enable/disable an item, programmatically.
I searched but cannot find how to do that. I found MenuLinkManager, MenuLinkContent, but I can't do what I want.
Thank you all for your help.

Assuming you actually want to remove the link I would use hook_menu_links_discovered_alter()
For example:
/**
* Implements hook_menu_links_discovered_alter().
*
* #param array $links
* An array of links.
*/
function HOOK_menu_links_discovered_alter(array &$links): void {
unset($links['machine_name_to_remove']);
}

To Disable/Enable Menu items means show/hide it. So, we can do it via below code in theme file
/**
* Implements hook_preprocess_menu().
*/
function theme_preprocess_menu(&$variables) {
if (isset($variables['menu_name']) && $variables['menu_name'] === 'main') {
foreach($variables['items'] as $key => $item) {
$path = $item['url']->toString();
switch($path) {
case '/menupath':
unset($variables['items'][$key]); //Remove menu item
break;
}
}
}
}

You can install the module Special Menu Items
https://www.drupal.org/project/special_menu_items
Or do it in your theme_link function in your template.php
function myTheme_link($variables) {
if ((isset($variables['path']) && ($variables['path'] == $_GET['q'] || ($variables['path'] == '<front>' && drupal_is_front_page())))) {
return ($variables['options']['html'] ? $variables['text'] : check_plain($variables['text']));
} else {
return '<a href="' . check_plain(url($variables['path'], $variables['options'])) . '"' . drupal_attributes($variables['options']['attributes']) . '>' . ($variables['options']['html'] ? $variables['text'] : check_plain($variables['text'])) . '</a>';
}
}

You need to exclude the menu from cache if you are going to alter it dynamically:
/**
* Implements hook_preprocess_HOOK().
*/
function YOUR_MODULE_preprocess_menu(&$variables) {
foreach ($variables['items'] as $key => $item) {
if ($key == 'depot_opm.document_demande_existant_tabs') {
unset($variables['items'][$key]);
}
}
}
/**
* Implements hook_preprocess_HOOK().
*/
function YOUR_MODULE_preprocess_block(&$variables) {
// Disable the cache of the menu block.
if($variables['derivative_plugin_id'] == 'tabs-documents') {
$variables['#cache']['max-age'] = 0;
}
}

This is what worked for me: tested with Drupal 9.3.9 (April 2022).
/**
* Implements hook_menu_links_discovered_alter().
*/
function MY_MODULE_menu_links_discovered_alter(&$links) {
$links['standard.front_page']['enabled'] = 0;
}

Related

Find if featured image on page has changed

While looking into this question I came up with the following solution that is called from canDelete() in an extension to File:
protected function isFileInUse()
{
$owner = $this->getOwner();
$dataObjectSubClasses = ClassInfo::subclassesFor('DataObject');
$classesWithFileHasOne = [];
foreach ($dataObjectSubClasses as $subClass) {
$hasOnes = array_flip($subClass::create()->hasOne());
if (array_key_exists($owner->class, $hasOnes)) {
$classesWithFileHasOne[$subClass] = $hasOnes[$owner->class];
}
}
$threshold = (Director::get_current_page()->class == 'AssetAdmin') ? 1 : 2;
$uses = 0;
foreach ($classesWithFileHasOne as $class => $relation) {
$uses += count($class::get()->filter("{$relation}ID", $this->owner->ID));
if ($uses >= $threshold) {
return true;
}
}
return false;
}
There is one edge case I can't get around though. If, say, a featured image is changed on a blog post then if there is exactly one other use of the same image then with this approach it will still allow it to be deleted. This is because until the page is saved the current change doesn't count towards uses of the image.
The threshold is set differently in CMS Pages and the Media Manager to allow an image to be deleted from within the page that is using it.
Is there a way that I can access the containing page (or other element - we're using Elemental) from within my File extension to see if its associated image has changed?
This is the solution I eventually came up with. I'm not entirely happy with having to inspect the request but couldn't see any other solution:
public function canDelete($member = null)
{
return !$this->isFileInUse();
}
/**
* Check if the file is in use anywhere on the site
* #return bool True if the file is in use
*/
protected function isFileInUse()
{
$owner = $this->getOwner();
$dataObjectSubClasses = ClassInfo::subclassesFor('DataObject');
$classesWithFileHasOne = [];
foreach ($dataObjectSubClasses as $subClass) {
$hasOnes = array_flip($subClass::create()->hasOne());
if (array_key_exists($owner->class, $hasOnes)) {
$classesWithFileHasOne[$subClass] = $hasOnes[$owner->class];
}
}
$threshold = ($this->isAssetAdmin() || ($this->isFileAttach($classesWithFileHasOne))) ? 1 : 2;
$uses = 0;
foreach ($classesWithFileHasOne as $class => $relation) {
$uses += count($class::get()->filter("{$relation}ID", $this->owner->ID));
if ($uses >= $threshold) {
return true;
}
}
return false;
}
/**
* Are we in the asset manager rather than editing a Page or Element?
* #return bool
*/
protected function isAssetAdmin()
{
return 'AssetAdmin' === Director::get_current_page()->class;
}
/**
* Is the current action attaching a file to a field that we're interested in?
* #param array $classesWithFileHasOne Classes with a relationship we're interested in and the name of the
* relevant field
* #return bool
*/
protected function isFileAttach($classesWithFileHasOne)
{
$controller = Controller::curr();
$field = $controller->request->allParams()['FieldName'];
return (preg_match('/attach$/', $controller->requestParams['url']) &&
($controller->action == 'EditForm')
&& (in_array($field, array_values($classesWithFileHasOne))));
}

Custom Article Field not showing up in joomla 3.2

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

Conflict between the extensions SCP (Simple Configurable Products) and Firegento German Setup

I've just installed the Magento extension Firegento German Setup and it works fine. Unfortunately another extension SCP (Simple Configurable Products), shows some undesired behavior now. The field "Price from" - which is created by SCP for articles - vanishes after the installation of Firegento German Setup. When un-installing Firegento again, SCP shows the field "Price from" as before. Obviously, the SCP field "Price from" is overridden by Firegento. Both extensions have their own "price.php" and I guess the conflict is with these two files. Does anyone know a solution? Please help, thanks in advance.
Mario
Below the price.php of the extension SCP Simple Configurable Products
public function _toHtml() {
$htmlToInsertAfter = '<div class="price-box">';
if ($this->getTemplate() == 'catalog/product/price.phtml') {
$product = $this->getProduct();
if (is_object($product) && $product->isConfigurable()) {
$extraHtml = '<span class="label" id="configurable-price-from-'
. $product->getId()
. $this->getIdSuffix()
. '"><span class="configurable-price-from-label">';
if ($product->getMaxPossibleFinalPrice() != $product->getFinalPrice()) {
$extraHtml .= $this->__('Price From:');
}
$extraHtml .= '</span></span>';
$priceHtml = parent::_toHtml();
#manually insert extra html needed by the extension into the normal price html
return substr_replace($priceHtml, $extraHtml, strpos($priceHtml, $htmlToInsertAfter)+strlen($htmlToInsertAfter),0);
}
}
return parent::_toHtml();
}
And here comes the price.php of the extension Firegento_
*/
public function _toHtml()
{
$html = trim(parent::_toHtml());
if (empty($html) || !Mage::getStoreConfigFlag('catalog/price/display_block_below_price')) {
return $html;
}
if (!in_array($this->getTemplate(), $this->_tierPriceDefaultTemplates)) {
$htmlObject = new Varien_Object();
$htmlObject->setParentHtml($html);
$htmlTemplate = $this->getLayout()->createBlock('core/template')
->setTemplate('germansetup/price_info.phtml')
->setFormattedTaxRate($this->getFormattedTaxRate())
->setIsIncludingTax($this->isIncludingTax())
->setIsIncludingShippingCosts($this->isIncludingShippingCosts())
->setIsShowShippingLink($this->isShowShippingLink())
->setIsShowWeightInfo($this->getIsShowWeightInfo())
->setFormattedWeight($this->getFormattedWeight())
->toHtml();
$htmlObject->setHtml($htmlTemplate);
$this->_addDeliveryTimeHtml($htmlObject);
Mage::dispatchEvent('germansetup_after_product_price',
array(
'html_obj' => $htmlObject,
'block' => $this,
)
);
$html = $htmlObject->getPrefix();
$html .= $htmlObject->getParentHtml();
$html .= $htmlObject->getHtml();
$html .= $htmlObject->getSuffix();
}
return $html;
}
/**
* Add delivery time on category pages only
*
* #param $htmlObject
*/
protected function _addDeliveryTimeHtml($htmlObject)
{
if (!Mage::getStoreConfigFlag('catalog/price/display_delivery_time_on_categories')) {
return;
}
$pathInfo = Mage::app()->getRequest()->getPathInfo();
if (strpos($pathInfo, 'catalog/category/view') !== false
|| strpos($pathInfo, 'catalogsearch/result') !== false) {
if ($this->getProduct()->getDeliveryTime()) {
$html = '<p class="delivery-time">';
$html .= $this->__('Delivery Time') . ': ' . $this->getProduct()->getDeliveryTime();
$html .= '</p>';
$htmlObject->setSuffix($html);
}
}
}
/**
* Read tax rate from current product.
*
* #return string
*/
public function getTaxRate()
{
$taxRateKey = 'tax_rate_'.$this->getProduct()->getId();
if (!$this->getData($taxRateKey)) {
$this->setData($taxRateKey, $this->_loadTaxCalculationRate($this->getProduct()));
}
return $this->getData($taxRateKey);
}
/**
* Retrieves formatted string of tax rate for user output
*
* #return string
*/
public function getFormattedTaxRate()
{
if ($this->getTaxRate() === null
|| $this->getProduct()->getTypeId() == 'bundle'
) {
return '';
}
$locale = Mage::app()->getLocale()->getLocaleCode();
$taxRate = Zend_Locale_Format::toFloat($this->getTaxRate(), array('locale' => $locale));
return $this->__('%s%%', $taxRate);
}
/**
* Returns whether or not the price contains taxes
*
* #return bool
*/
public function isIncludingTax()
{
if (!$this->getData('is_including_tax')) {
$this->setData('is_including_tax', Mage::getStoreConfig('tax/display/type'));
}
return $this->getData('is_including_tax');
}
/**
* Returns whether or not the price contains taxes
*
* #return bool
*/
public function isIncludingShippingCosts()
{
if (!$this->getData('is_including_shipping_costs')) {
$this->setData(
'is_including_shipping_costs',
Mage::getStoreConfig('catalog/price/including_shipping_costs')
);
}
return $this->getData('is_including_shipping_costs');
}
/**
* Returns whether the shipping link needs to be shown
* on the frontend or not.
*
* #return bool
*/
public function isShowShippingLink()
{
$productTypeId = $this->getProduct()->getTypeId();
$ignoreTypeIds = array('virtual', 'downloadable');
if (in_array($productTypeId, $ignoreTypeIds)) {
return false;
}
return true;
}
/**
* Gets tax percents for current product
*
* #param Mage_Catalog_Model_Product $product
* #return string
*/
protected function _loadTaxCalculationRate(Mage_Catalog_Model_Product $product)
{
$taxPercent = $product->getTaxPercent();
if (is_null($taxPercent)) {
$taxClassId = $product->getTaxClassId();
if ($taxClassId) {
$request = Mage::getSingleton('tax/calculation')->getRateRequest(null, null, null, null);
$taxPercent = Mage::getSingleton('tax/calculation')->getRate($request->setProductClassId($taxClassId));
}
}
if ($taxPercent) {
return $taxPercent;
}
return 0;
}
/**
* Check if Shipping by Weight is active
*
* #return bool
*/
public function getIsShowWeightInfo()
{
return Mage::getStoreConfigFlag('catalog/price/display_product_weight');
}
/**
* Get formatted weight incl. unit
*
* #return string
*/
public function getFormattedWeight()
{
return floatval($this->getProduct()->getWeight()) . ' ' . Mage::getStoreConfig('catalog/price/weight_unit');
}
/**
* Translate block sentence
*
* #return string
*/
public function __()
{
$args = func_get_args();
$expr = new Mage_Core_Model_Translate_Expr(array_shift($args), 'Mage_Catalog');
array_unshift($args, $expr);
return Mage::app()->getTranslator()->translate($args);
}
}
I had the exact same problem and solved it this way:
Copy the price.php of firegento to your local folder
Add this Code below
$htmlToInsertAfter = '<div class="price-box">';
if ($this->getTemplate() == 'catalog/product/price.phtml') {
$product = $this->getProduct();
if (is_object($product) && $product->isConfigurable()) {
$extraHtml = '<span class="label" id="configurable-price-from-'
. $product->getId()
. $this->getIdSuffix()
. '"><span class="configurable-price-from-label">';
if ($product->getMaxPossibleFinalPrice() != $product->getFinalPrice()) {
$extraHtml .= $this->__('Price from:');
}
$extraHtml .= '</span></span>';
#manually insert extra html needed by the extension into the normal price html
$html = substr_replace($html, $extraHtml, strpos($html, $htmlToInsertAfter)+strlen($htmlToInsertAfter),0);
}
}
below
$html = trim(parent::_toHtml());
inside the _toHtml() method in price.php.
It is the code of the Simple Configurable Products price.php with minor adjustments.
Hope that helps

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